size_t strlen(char const string[static 1]);
int main(int argc, char* argv[argc+1]);
It's worth a look at C11 as well, some of what you might have used gcc or clang attributes for has climbed into the language, such as _Noreturn, _Alignas, _Alignof and their friend aligned_alloc().
Addendum: Well, you can pass in pointers that go to fewer elements, but you can't pass in an actual naked null.
It's nice to be able to specify function's expectations on that level, yet it looks that only clang (tested with 3.5.0) takes use of it, while gcc (tested with 4.9.1) seems oblivious to it. Be it NULL or shorter string literal than expected, gcc with -Wall -Wextra -pedantic -std=c99 spits nothing. Both mistakes are detected by clang.
Sadly even clang doesn't warn us when fun(int len, char str[static len+1]) is called like fun(5, "test").
But I'm not sure that I agree with the rule 22.214.171.124 Don't use NULL. In any sane C environment NULL is defined as follows (unless __cplusplus is already defined, because then it's defined as 0 or 0L)
#define NULL ((void*)0)
Distinguishing kind of 0 we're dealing with (even if it's not strongly guarded by compiler) is often important for readability and eases maintenance of the code (0 vs '\0' vs NULL). While comparing pointer with NULL (writing p == NULL or p != NULL instead of simply !p or p) may seem superfluous (yet I have nothing against programmers doing so), calling function with pointer parameters providing 0 argument instead of NULL seems less clear to me.
> if you really want to emphasize that the value is a pointer use the magic token sequence (void *)0 directly.
I don't buy it.
There was also discussion on musl mailing list (I don't know is this best link to it): http://www.openwall.com/lists/musl/2013/01/09/1
C++ is another story with its
In many cases you can be done with 0 alone in C++, that's true, and in such cases NULL at least poses some intention, but if you're not careful enough, you may end up putting NULL alone (without pointer-to-type cast) in some variadic function and things start to blow up all of a sudden (that is if your NULL integer width isn't the same as pointer width). That's why having a habit of writing
Regarding musl check also:
In short, musl's stddef.h has following lines:
#define NULL 0L
#define NULL ((void*)0)
In the same vein for Windows C++ x64 environment you need NULL to be 0LL, as it is LLP64 platform.
Update: He wrote back and agreed.
- Pages 156 to 164 are missing (I tried to skip straight to the "Ambition" section but couldn't find it).
- The first sentence, "It has been a long time since the programming language C is around" sounds wrong to a native English speaker. Say "The C programming language has been around for a long time" or "It has been a long time since the C programming language appeared". "Since" in English generally refers to things that happened in perfect tenses (as opposed to e.g. "depuis" in French that has an imperfect tone).
Hope these are helpful. Book sounds great.
I also really like that the book can be read by people of varying levels of experience, with sections devoted to different groups.
The C99 subset that was added was what is required by C++11/C++14 standards and some key customers.
There are no plans for full ANSI C compliance, as discussed here
And if it's modern C, why not use the typedefs from stdint.h?
Also, while it's true that modern C has the stdint.h typedefs, the old types are still good. All of the standard library, and many libraries you use, use the old types, so this makes interaction with them more practical. Furthermore, it'd probably best to use sizes suited to your platform. A long will be 32-bit on a 32-bit system and 64-bit on a 64-bit system. You only need long long in some cases. You can't avoid the traditional C types for things like strings, either.
Really, stdint.h only matters if you're reading binary data or performance is ultra-important, IMO.
IMO unsigned integers shouldn't have a subtraction operator named '-'. The semantics are sufficiently different that a subtraction operation on unsigneds should stand out.
(I am not a fan of using unsigned integers for semantically non-negative numbers. They are not simply a non-negative bounded type; they are a different type of integer, with a different arithmetic not familiar to everyday maths. But this is a tough row to hoe in C. Other languages, like Java and C#, didn't inherit the same mistake.)
Probably not as often as you use subtraction.
Plus, gcc has -fsanitize=signed-integer-overflow.
Not on Windows. Long is there always 32 bits.
half of it is about tools (valgrind, make, autoconf)
and it also talks about libraries (sqlite, gsl, etc...)
of course there are some chapters about the language itself
FWIW tptacek likes C Interfaces and Implementations by Hanson, wonder how that compares.
A bit meta:
Looking for a book in a particular subject, I picked one because of a number of the reviews I read, but actually reading the book dampened my enthusiasm.
I don't know about this particular book, but if the subject is worth it it is probably also worth your time to check it out yourself :-).