Contents|Index|Previous|Next

Self-Referential Macros

A self-referential macro is one whose name appears in its definition. A special feature of ANSI Standard C is that the self-reference is not considered a macro call. It is passed into the preprocessor output unchanged.

Let’s consider an example.

    #define foo (4 + foo)

foo, then, is also a variable in your program.

Following the ordinary rules, each reference to foo will expand into (4+foo); then this will be re-scanned and will expand into (4+(4+foo)); and so on until it causes a fatal error (memory full) in the preprocessor.

However, the special rule about self-reference cuts this process short after one step at (4 + foo). So, this macro definition has the possibly useful effect of causing the program to add 4 to the value of foo wherever foo is referred to. In most cases, it is a bad idea to take advantage of this feature. A person reading the program who sees that foo is a variable will not expect that it is a macro as well. The reader will come across the identifier foo in the program and think its value should be that of the variable foo, whereas in fact the value is four greater. The special rule for self-reference applies also to indirect self-reference. This is the case where a macro x expands to use a macro y, and the expansion of y refers to the macro x. The resulting reference to x comes indirectly from the expansion of x, so it is a self-reference and is not further expanded. Suppose you used the following input.

    #define x (4 + y)
    #define y (2 * x)

x, then, would expand into (4+(2*x)). Clear?

But suppose y is used elsewhere, not from the definition of x. Then the use of x in the expansion of y is not a self-reference because x is not in progress. So it does expand. However, the expansion of x contains a reference to y, and that is an indirect self-reference now because y is in progress. The result is that y expands to (2*(4+y)). It is not clear that this behavior would ever be useful, but it is specified by the ANSI C standard, so you may need to understand it.