Bruce Eckel's Thinking in C++, 2nd Ed Contents | Prev | Next

More preprocessor features

Earlier, I said 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, by inheritance, the C++ preprocessor): stringizing, string concatenation, and token pasting. Stringizing, performed with the # directive, allows you to take an identifier and turn it into a string, whereas string concatenation takes place when two adjacent strings have no intervening punctuation, in which case the strings are combined. These two features are exceptionally 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) cout << #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.

Token pasting

Token pasting is very useful when you are manufacturing code. It allows you to take two identifiers and paste them together to automatically create a new identifier. For example,

#define FIELD(A) char* A##_string; int A##_size
class Record {
  FIELD(one);
  FIELD(two);
  FIELD(three);
  // ...
};

Each call to the FIELD( ) macro creates an identifier to hold a string and another to hold the length of that string. Not only is it easier to read, it can eliminate coding errors and make maintenance easier. Notice, however, the use of all upper-case characters in the name of the macro. This is a helpful practice because it tells the reader this is a macro and not a function, so if there are problems, it acts as a little reminder.

Contents | Prev | Next


Contact: webmaster@codeguru.com
CodeGuru - the website for developers.
[an error occurred while processing this directive]