Channels ▼
RSS

Open Source

Code Finessing


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, implemented—you guessed it—through 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 code—internal 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.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video