Go to the first, previous, next, last section, table of contents.


5.3 Safety and Clarity

Avoid macros! Macros are a major source of bugs. Use procedures instead. Once your code is working, and you find yourself with extra time on your hands, then you can replace some procedures with macros for minor performance gains, although we still do not recommend wasting your time this way.

All source code should make abundant use of the assert() macro from the `<assert.h>' library for both clarity and correctness. Correctness includes checking that procedures are passed the proper arguments and that they return proper values. Clarity includes asserting all known invariants and assumptions. As a rough guide, around 50% of your code should be asserts, as high as 75% when performing pointer arithmetic. No kidding. The source code must work properly even if NDEBUG is defined and all the assert() macros vanish. That means no side-effects may occur in the expressions passed to assert().

Replace compound asserts with primitive asserts in order to make debugging easier. For example, the compound assertion

assert(exp1 && exp2);

should be replaced with the two primitive assertions

assert(exp1); assert(exp2);

Do not mutate a variable inside a complex expression or when it appears as an argument to a procedure call. If this restriction makes you whine about typing effort, then it's time to take another typing class. Thus, f(i++); should be f(i); i++.

All blocks must be explicitly delimited by curly brackets, especially if the blocks contain exactly one statement, eg.,

if (predicate) { statement; }

Liberal use of parentheses is encouraged, particularly within macro definitions. Programming is not a test to see whether you know all the most compact legal expressions of C. Rather, it is a test to see if you can write correct code of breathtaking clarity.

Cutting and pasting code is likely to introduce errors. It is also an early warning sign of a bad modularization. So don't do it! If you are unable to break your cut-and-paste habit, then you must review newly pasted code with extraordinary diligence.


Go to the first, previous, next, last section, table of contents.