The C Preprocessor
The power of the C/C++ preprocessor macros comes from two deceptively simple constructs. With the preprocessor's object-like macros, such as #define PI 3.1415927, you can define compile-time constants and guide conditional compilation; with function-like macros such as #define sqr(x) ((x) * (x)), you can write inline and generic functions. Both facilities can also be used or abused to morph your code closer toward forms you believe to be more readable than plain C/C++. (An early implementation of the UNIX shell appeared to be written in an Algol-like language, implementedyou guessed itthrough C macros.)
However, the apparent simplicity of these two constructs is just the lid on the proverbial can of worms. A macro can call other macros, it can generate new macro names as a result of its expansion, and it can also recursively call itself. Correctly handling these cases when implementing the preprocessor is anything but simple. If the expansion is too conservative, then some pretty amazing code that relies on the preprocessor ceases to work. For example, the Boost preprocessor library (www.boost.org/libs/preprocessor/doc/index.html) uses nested macro expansions to provide powerful generative metaprogramming facilities: code constructs that generate other code at compile time. More spectacularly, two past winners of the Obfuscated C Code Contest (www.ioccc.org) had the preprocessor generate a list of prime numbers. If, on the other hand, the expansion is too aggressive, the preprocessor will go into an endless loop. This is definitely not something we would want to happen when we compile our codeinternal compiler errors are bad enough.
Fortunately, the C Standardization Committee has set precise rules for determining when nested macros can be recursively expanded. The relevant wording in the C Standard is as follows (hold your breath):
Then, the resulting preprocessing token sequence is rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace. If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file's preprocessing tokens), it is not replaced. Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced. These nonreplaced macro name-preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.
Understanding and implementing this specification is anything but simple. Specialists use the (literally) colorful expression "painting a macro with blue paint" to refer to the concept of hiding macros that have already been replaced. A search for preprocessor and "blue paint" in Google gives you many heated discussions arguing over the finer points of this specification.