C/C++ Preprocessor Macro Idioms

I’ve been tormented the past few days about an article I read several years ago. I barely even remember what it was about, only that the author played very clever tricks with the preprocessor’s token pasting functionality to push the limits of what the preprocessor can do. Maybe it was a parameterized repetition macro? Something like that. I do remember it took advantage of the asymmetry in expansion between function-like and object-like macros.

Anyways, I’ve been poking around the (very nice!) Chromium source code. One thing I took a close look at is how Google organized their logging macros. In the process, I noticed two tricks they used that I think are effectively preprocessor idioms, and since Google doesn’t turn up much for that search phrase, I figured I’d document what I saw.

The external interface of the Google logging system is pretty simple: the LOG macro takes a severity parameter, such as INFO or ERROR and expands into a temporary object that derives from std::ostream. The tricks have to do with the severities: the tokens used as severities aren’t #defined to the preprocessor! Instead, whatever is passed in is pasted onto a longer token that expands to an object declaration with the desired parameters. This lack of actual #define statements effectively gives the severity tokens a specific local scope, even though the preprocessor deals only with explicitly global scope. And the one-to-many trick effectively forms a preprocessor-style switch() construct, where the macro parameter can affect the expansion of the rest of the macro.

Incidentally, now that I look, the Boost preprocessor library uses the same switch() trick to implement BOOST_PP_IF. Nifty.

Advertisements

One thought on “C/C++ Preprocessor Macro Idioms

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s