C preprocessor
C preprocessor
The C preprocessor is a powerful tool and properly used may be very useful. The following have been checked to work in GCC.
Rules
Uses
Uses for debugging
Assertions are used to catch situations which should never happen, even under error circumstances.
#define assert(x) do { if (!(x)) { complain("assertion fail"); panic(); } } while(0) assert( sizeof(struct free_memory_block) == 8 ); assert( 1 != 2 ); assert( gdt_ptr != null );
Assertions may be turned off in production code
#define assert(x) do {} while(0)
Some rare unrecoverable errors should be tested for also in production code and these test should not be disabled so that we recognise the problem instead of having random crashes
#define testif(x) do { if (!(x)) { complain("testif fail"); panic(); } } while(0) testif( isChecksumCorrect( kernel_heap.first_free_list ) ); testif( timersAreOn );
Deleted Code
A code block may be commented out to delete it from the program, however nesting deleted fragments may reduce legibility with C++ style comments, and C comments do not nest at all. A better solution is to wrap the code in and #if 0-#endif block, where the conditional 0 means false :
#if 0 print("memory state: "); print(mem->state); print("\nallocated blocks: "); print(mem->allocs); #endif
Many editors, like VIm have by default syntax highlighting rules that treat such #if 0-#endif blocks as comments. The #if-#endif directives must be balanced, single-quotes characters must balance etc. so for deleting non-code text use comments instead.
Hazards of the C preprocessor
There is a number of counter-intuitive consequences of macros and macro expanding design. Macro Pitfalls
See also
External Links
The GNU C preprocessor manual: