More preprocessor features
Earlier, I said that you almost
always want to use inline functions instead of preprocessor macros. The
exceptions are when you need to use three special features in the C preprocessor
(which is also the C++ preprocessor):
stringizing, string
concatenation, and token
pasting. Stringizing, introduced
earlier in the book, is performed with the # directive and allows you to
take an identifier and turn it into a character array. String concatenation
takes place when two adjacent character arrays have no intervening punctuation,
in which case they are combined. These two features are especially useful when
writing debug code. Thus,
#define DEBUG(x) cout << #x " = " << x << endl
This prints the value of any variable.
You can also get a trace that prints out the statements as they
execute:
#define TRACE(s) cerr << #s << endl; s
The #s stringizes the statement
for output, and the second s reiterates the statement so it is executed.
Of course, this kind of thing can cause problems, especially in one-line
for loops:
for(int i = 0; i < 100; i++)
TRACE(f(i));
Because there are actually two statements
in the TRACE( ) macro, the one-line for loop executes only
the first one. The solution is to replace the semicolon with a comma in the
macro.