| 5.58 In two’s complement representation, INT_MIN < -INT_MAX. | |
| 5.59 Negation may overflow for signed arithmetic. | |
| 5.60 Use unsigned types for bit operations. | |
| 5.61 If the type uintN_t is provided, it is an unsigned integer type with exactly N bits of width and precision. | |
| 5.62 If the type intN_t is provided, it is signed, with two’s complement representation and has a width of exactly N bits and a precision of N – 1. | |
| 5.63 If types with the required properties exist for values of N = 8, 16, 32, and 64, types uintN_t and intN_t, respectively, must be provided. | |
| 5.64 For any of the fixed-width types that are provided, _MIN (only signed), maximum _MAX, and literals _C macros are provided, too. | |
| 5.65 Floating-point operations are neither associative, commutative, nor distributive. | |
| 5.66 Never compare floating-point values for equality. | |
| 6.1 Arrays are not pointers. | |
| 6.2 An array in a condition evaluates to true. | |
| 6.3 There are array objects but no array values. | |
| 6.4 Arrays can’t be compared. | |
| 6.5 Arrays can’t be assigned to. | |
| 6.6 VLAs can’t have initializers. | |
| 6.7 VLAs can’t be declared outside functions. | |
| 6.8 The length of an FLA is determined by an integer constant expression (ICE) or by an initializer. | |
| 6.9 An array-length specification must be strictly positive. | |
| 6.10 An array with a length that is not an integer constant expression is a VLA. | |
| 6.11 The length of an array A is (sizeof A)/(sizeof A[0]). | |
| 6.12 The innermost dimension of an array parameter to a function is lost. | |
| 6.13 Don’t use the sizeof operator on array parameters to functions. | |
| 6.14 Array parameters behave as if the array is passed by referenceC. | |
| 6.15 A string is a 0-terminated array of char. | |
| 6.16 Using a string function with a non-string has undefined behavior. | |
| 6.17 Pointers are opaque objects. | |
| 6.18 Pointers are valid, null, or indeterminate. | |
| 6.19 Initialization or assignment with 0 makes a pointer null. | |
| 6.20 In logical expressions, pointers evaluate to false if they are null. | |
| 6.21 Indeterminate pointers lead to undefined behavior. | |
| 6.22 Always initialize pointers. | |
| 6.23 Omitted struct initializers force the corresponding member to 0. | |
| 6.24 A struct initializer must initialize at least one member. | |
| 6.25 struct parameters are passed by value. | |
| 6.26 Structures can be assigned with = but not compared with == or !=. | |
| 6.27 A structure layout is an important design decision. | |
| 6.28 All struct declarations in a nested declaration have the same scope of visibility. | |
| 6.29 Forward-declare a struct within a typedef using the same identifier as the tag name. | |
| 6.30 A typedef only creates an alias for a type, but never a new type. | |
| 6.31 Identifier names terminating with _t are reserved. | |
| 7.1 All functions must have prototypes. | |
| 7.2 Functions have only one entry but can have several returns. | |
| 7.3 A function return must be consistent with its type. | |
| 7.4 Reaching the end of the {} block of a function is equivalent to a return statement without an expression. | |
| 7.5 Reaching the end of the {} block of a function is only allowed for void functions. | |
| 7.6 Use EXIT_SUCCESS and EXIT_FAILURE as return values for main. | |
| 7.7 Reaching the end of main is equivalent to a return with value EXIT_SUCCESS. | |
| 7.8 Calling exit(s) is equivalent to the evaluation of return s in main. | |
| 7.9 exit never fails and never returns to its caller. | |
| 7.10 All command-line arguments are transferred as strings. | |
| 7.11 Of the arguments to main, argv[0] holds the name of the program invocation. | |
| 7.12 Of the arguments to main, argv[argc] is 0. | |
| 7.13 Make all preconditions for a function explicit. | |
| 7.14 In a recursive function, first check the termination condition. | |
| 7.15 Ensure the preconditions of a recursive function in a wrapper function. | |
| 7.16 Multiple recursion may lead to exponential computation times. | |
| 7.17 A bad algorithm will never lead to a implementation that performs well. | |
| 7.18 Improving an algorithm can dramatically improve performance. | |
| 8.1 Failure is always an option. | |
| 8.2 Check the return value of library functions for errors. | |
| 8.3 Fail fast, fail early, and fail often. | |
| 8.4 Identifier names terminating with _s are reserved. | |
| 8.5 Missed preconditions for the execution platform must abort compilation. | |
| 8.6 Only evaluate macros and integer literals in a preprocessor condition. | |
| 8.7 In preprocessor conditions, unknown identifiers evaluate to 0. | |
| 8.8 Opaque types are specified through functional interfaces. | |
| 8.9 Don’t rely on implementation details of opaque types. | |
| 8.10 puts and fputs differ in their end-of-line handling. | |
| 8.11 Text input and output converts data. | |
| 8.12 There are three commonly used conversions to encode end-of-line. | |
| 8.13 Text lines should not contain trailing white space. | |
| 8.14 Parameters of printf must exactly correspond to the format specifiers. | |
| 8.15 Use "%d" and "%u" formats to print integer values. | |
| 8.16 Use the "%x" format to print bit patterns. | |
| 8.17 Use the "%g" format to print floating-point values. | |
| 8.18 Using an inappropriate format specifier or modifier makes the behavior undefined. | |
| 8.19 Use "%+d", "%#X", and "%a" for conversions that have to be read later. | |
| 8.20 Don’t use gets. | |
| 8.21 fgetc returns int to be able to encode a special error status, EOF, in addition to all valid characters. | |
| 8.22 End of file can only be detected after a failed read. | |
| 8.23 The interpretation of numerically encoded characters depends on the execution character set. | |
| 8.24 Regular program termination should use a return from main. | |
| 8.25 Use exit from a function that may terminate the regular control flow. | |
| 8.26 Don’t use functions other than exit for program termination, unless you have to inhibit the execution of library cleanups. | |
| 8.27 Use as many asserts as you can to confirm runtime properties. | |
| 8.28 In production compilations, use NDEBUG to switch off all assert. | |
| C All C code must be readable. | |
| 9.1 Short-term memory and the field of vision are small. | |
| 9.2 Coding style is not a question of taste but of culture. | |
| 9.3 When you enter an established project, you enter a new cultural space. | |
| 9.4 Choose a consistent strategy for white space and other text formatting. | |
| 9.5 Have your text editor automatically format your code correctly. | |
| 9.6 Choose a consistent naming policy for all identifiers. | |
| 9.7 Any identifier that is visible in a header file must be conforming. | |
| 9.8 Don’t pollute the global space of identifiers. | |
| 9.9 Names must be recognizable and quickly distinguishable. | |
| 9.10 Naming is a creative act. | |
| 9.11 File-scope identifiers must be comprehensive. | |
| 9.12 A type name identifies a concept. | |
| 9.13 A global constant identifies an artifact. |