“Modern C”: Notes on preamble “Level 1 Aquaintance”
By Dmitry Kabanov
These are my notes taken while reading the preamble for the part “Level 1. Aquaintance” from the book “Modern C” by Jens Gustedt. This preamble introduces stylistic decisions that the author uses in the rest of the book.
The table of contents for all notes for this book are available in that post.
The types and identifiers are visually separated.
For examples, pointer variables have *
attached to the type:
char* str;
The qualifiers are left-binding also:
char const* const path_name;
Declaring several variables on the same line is not allowed:
unsigned const* const a, b; // BAD
Here, the second const
is applied only to a
, which makes
everything really confusing for the reader.
For functions that accept pointer parameters, array notation is used
whenever the pointer is not allowed to be NULL
:
size_t strlen(char const string[static 1]);
int main(int argc, char *argv[argc+1]);
Here we emphasize that strlen
accepts a string with at least one
charater (nul
-terminator), and main
accepts an array of type
char *
(hmm, here the author breaks his own rule about *
) with
argc+1
elements (such an array contains nul
-terminator as the
sentinel.
Anywhere, compatible declarations can be used without any complaints from the compiler:
size_t strlen(const char *string);
int main(int argc, char **argv);
For function pointer parameters, the first notation is preferred:
int atexit(void handler(void));
int atext(void (*handler)(void));
All variables must be defined as close as possible to the place
where they used.
Particularly, it means that the iteration variables in for
loops
must be declared inside the loop.
Opening braces are always on the same line as the corresponding block statement, closing braces have the same indent as the block statement, and continued block statements are on the same line as the closing braces:
int main(void) {
while (true) {
if (A) {
// Do this
} else {
// Do that
}
}
return 0;
}