Conditional compilation is useful for things like machine-dependencies, debugging, and for setting certain options at compile-time. Beware of conditional compilation. Various controls can easily combine in unforeseen ways. If you #ifdef machine dependencies, make sure that when no machine is specified, the result is an error, not a default machine. (Use "#error" and indent it so it works with older compilers.) If you #ifdef optimizations, the default should be the unoptimized code rather than an uncompilable program. Be sure to test the unoptimized code.
Note that the text inside of an #ifdeffed section may be scanned (processed) by the compiler, even if the #ifdef is false. Thus, even if the #ifdeffed part of the file never gets compiled (e.g., #ifdef COMMENT), it cannot be arbitrary text.
Put #ifdefs in header files instead of source files when possible. Use the #ifdefs to define macros that can be used uniformly in the code. For instance, a header file for checking memory allocation might look like (omitting definitions for REALLOC and FREE):
#ifdef DEBUG extern void *mm_malloc(); # define MALLOC(size) (mm_malloc(size)) #else extern void *malloc(); # define MALLOC(size) (malloc(size)) #endif
Conditional compilation should generally be on a feature-by-feature basis. Machine or operating system dependencies should be avoided in most cases.
#ifdef BSD4 long t = time ((long *)NULL); #endifThe preceding code is poor for two reasons: there may be 4BSD systems for which there is a better choice, and there may be non-4BSD systems for which the above is the best code. Instead, use define symbols such as TIME_LONG and TIME_STRUCT and define the appropriate one in a configuration file such as config.h.
contents
Macros
Debugging