| 9.14 A global variable identifies state. | |
| 9.15 A function or functional macro identifies an action. | |
| 10.1 (what) Function interfaces describe what is done. | |
| 10.2 (what for) Interface comments document the purpose of a function. | |
| 10.3 (how) Function code tells how the function is organized. | |
| 10.4 (in which manner) Code comments explain the manner in which function details are implemented. | |
| 10.5 Separate interface and implementation. | |
| 10.6 Document the interface—explain the implementation. | |
| 10.7 Document interfaces thoroughly. | |
| 10.8 Structure your code in units that have strong semantic connections. | |
| 10.9 Implement literally. | |
| 10.10 Control flow must be obvious. | |
| 10.11 Macros should not change control flow in a surprising way. | |
| 10.12 Function-like macros should syntactically behave like function calls. | |
| 10.13 Function parameters are passed by value. | |
| 10.14 Global variables are frowned upon. | |
| 10.15 Express small tasks as pure functions whenever possible. | |
| 11.1 Using * with an indeterminate or null pointer has undefined behavior. | |
| 11.2 A valid pointer refers to the first element of an array of the reference type. | |
| 11.3 The length of an array object cannot be reconstructed from a pointer. | |
| 11.4 Pointers are not arrays. | |
| 11.5 Only subtract pointers from elements of an array object. | |
| 11.6 All pointer differences have type ptrdiff_t. | |
| 11.7 Use ptrdiff_t to encode signed differences of positions or sizes. | |
| 11.8 For printing, cast pointer values to void*, and use the format %p. | |
| 11.9 Pointers have truth. | |
| 11.10 Set pointer variables to 0 as soon as you can. | |
| 11.11 Accessing an object that has a trap representation of its type has undefined behavior. | |
| 11.12 When dereferenced, a pointed-to object must be of the designated type. | |
| 11.13 A pointer must point to a valid object or one position beyond a valid object or be null. | |
| 11.14 Don’t use NULL. | |
| 11.15 Don’t hide pointers in a typedef. | |
| 11.16 The two expressions A[i] and *(A+i) are equivalent. | |
| 11.17 (array decay) Evaluation of an array A returns &A[0]. | |
| 11.18 In a function declaration, any array parameter rewrites to a pointer. | |
| 11.19 Only the innermost dimension of an array parameter is rewritten. | |
| 11.20 Declare length parameters before array parameters. | |
| 11.21 The validity of array arguments to functions must be guaranteed by the programmer. | |
| 11.22 (function decay) A function f without a following opening ( decays to a pointer to its start. | |
| 11.23 Function pointers must be used with their exact type. | |
| 11.24 The function call operator (...) applies to function pointers. | |
| 12.1 Pointer types with distinct base types are distinct. | |
| 12.2 sizeof(char) is 1 by definition. | |
| 12.3 Every object A can be viewed as unsigned char[sizeof A]. | |
| 12.4 Pointers to character types are special. | |
| 12.5 Use the type char for character and string data. | |
| 12.6 Use the type unsigned char as the atom of all object types. | |
| 12.7 The sizeof operator can be applied to objects and object types. | |
| 12.8 The size of all objects of type T is given by sizeof(T). | |
| 12.9 The in-memory order of the representation digits of an arithmetic type is implementation defined. | |
| 12.10 On most architectures, CHAR_BIT is 8 and UCHAR_MAX is 255. | |
| 12.11 (Aliasing) With the exclusion of character types, only pointers of the same base type may alias. | |
| 12.12 Avoid the & operator. | |
| 12.13 Any object pointer converts to and from void*. | |
| 12.14 An object has storage, type, and value. | |
| 12.15 Converting an object pointer to void* and then back to the same type is the identity operation. | |
| 12.16 (avoid2*) Avoid void*. | |
| 12.17 Don’t use casts. | |
| 12.18 (Effective Type) Objects must be accessed through their effective type or through a pointer to a character type. | |
| 12.19 Any member of an object that has an effective union type can be accessed at any time, provided the byte representation amounts to a valid value of the access type. | |
| 12.20 The effective type of a variable or compound literal is the type of its declaration. | |
| 12.21 Variables and compound literals must be accessed through their declared type or through a pointer to a character type. | |
| 13.1 Don’t cast the return of malloc and friends. | |
| 13.2 Storage that is allocated through malloc is uninitialized and has no type. | |
| 13.3 malloc indicates failure by returning a null pointer value. | |
| 13.4 For every allocation, there must be a free. | |
| 13.5 For every free, there must be a malloc, calloc, aligned_alloc, or realloc. | |
| 13.6 Only call free with pointers as they are returned by malloc, calloc, aligned_alloc, or realloc. | |
| 13.7 Identifiers only have visibility inside their scope, starting at their declaration. | |
| 13.8 The visibility of an identifier can be shadowed by an identifier of the same name in a subordinate scope. | |
| 13.9 Every definition of a variable creates a new, distinct object. | |
| 13.10 Read-only object literals may overlap. | |
| 13.11 Objects have a lifetime outside of which they can’t be accessed. | |
| 13.12 Referring to an object outside of its lifetime has undefined behavior. | |
| 13.13 Objects with static storage duration are always initialized. | |
| 13.14 Unless they are VLA or temporary objects, automatic objects have a lifetime corresponding to the execution of their block of definition. | |
| 13.15 Each recursive call creates a new local instance of an automatic object. | |
| 13.16 The & operator is not allowed for variables declared with register. | |
| 13.17 Variables declared with register can’t alias. | |
| 13.18 Declare local variables that are not arrays in performance-critical code as register. | |
| 13.19 Arrays with storage class register are useless. | |
| 13.20 Objects of temporary lifetime are read-only. | |
| 13.21 Temporary lifetime ends at the end of the enclosing full expression. | |
| 13.22 For an object that is not a VLA, lifetime starts when the scope of the definition is entered, and it ends when that scope is left. | |
| 13.23 Initializers of automatic variables and compound literals are evaluated each time the definition is met. | |
| 13.24 For a VLA, lifetime starts when the definition is encountered and ends when the visibility scope is left. | |
| 13.25 Objects of static or thread-storage duration are initialized by default. | |
| 13.26 Objects of automatic or allocated storage duration must be initialized explicitly. | |
| 13.27 Systematically provide an initialization function for each of your data types. | |
| 14.1 The string strto... conversion functions are not const-safe. | |
| 14.2 The memchr and strchr search functions are not const-safe. | |
| 14.3 The strspn and strcspn search functions are const-safe. | |
| 14.4 sprintf makes no provision against buffer overflow. | |
| 14.5 Use snprintf when formatting output of unknown length. | |
| 14.6 Multibyte characters don’t contain null bytes. | |
| 14.7 Multibyte strings are null terminated. | |
| 14.8 Open streams on which you use fread or fwrite in binary mode. | |
| 14.9 Files that are written in binary mode are not portable between platforms. | |
| 14.10 fseek and ftell are not suitable for very large file offsets. | |
| 14.11 Labels for goto are visible in the entire function that contains them. |