GNU Info

Info Node: (cpp-295.info)Self-Reference

(cpp-295.info)Self-Reference


Next: Argument Prescan Prev: Side Effects Up: Macro Pitfalls
Enter node , (file) or (file)node

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)

where `foo' is also a variable in your program.

   Following the ordinary rules, each reference to `foo' will expand
into `(4 + foo)'; then this will be rescanned 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)'.  Therefore, 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.  Thus, after

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

`x' 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.


automatically generated by info2www version 1.2.2.9