cpp: Traditional macros

1 
1 10.2 Traditional macros
1 =======================
1 
1 The major difference between traditional and ISO macros is that the
1 former expand to text rather than to a token sequence.  CPP removes all
1 leading and trailing horizontal whitespace from a macro's replacement
1 text before storing it, but preserves the form of internal whitespace.
1 
1    One consequence is that it is legitimate for the replacement text to
1 contain an unmatched quote (⇒Traditional lexical analysis).  An
1 unclosed string or character constant continues into the text following
1 the macro call.  Similarly, the text at the end of a macro's expansion
1 can run together with the text after the macro invocation to produce a
1 single token.
1 
1    Normally comments are removed from the replacement text after the
1 macro is expanded, but if the '-CC' option is passed on the command-line
1 comments are preserved.  (In fact, the current implementation removes
1 comments even before saving the macro replacement text, but it careful
1 to do it in such a way that the observed effect is identical even in the
1 function-like macro case.)
1 
1    The ISO stringizing operator '#' and token paste operator '##' have
1 no special meaning.  As explained later, an effect similar to these
1 operators can be obtained in a different way.  Macro names that are
1 embedded in quotes, either from the main file or after macro
1 replacement, do not expand.
1 
1    CPP replaces an unquoted object-like macro name with its replacement
1 text, and then rescans it for further macros to replace.  Unlike
1 standard macro expansion, traditional macro expansion has no provision
1 to prevent recursion.  If an object-like macro appears unquoted in its
1 replacement text, it will be replaced again during the rescan pass, and
1 so on _ad infinitum_.  GCC detects when it is expanding recursive
1 macros, emits an error message, and continues after the offending macro
1 invocation.
1 
1      #define PLUS +
1      #define INC(x) PLUS+x
1      INC(foo);
1           ==> ++foo;
1 
1    Function-like macros are similar in form but quite different in
1 behavior to their ISO counterparts.  Their arguments are contained
1 within parentheses, are comma-separated, and can cross physical lines.
1 Commas within nested parentheses are not treated as argument separators.
1 Similarly, a quote in an argument cannot be left unclosed; a following
1 comma or parenthesis that comes before the closing quote is treated like
1 any other character.  There is no facility for handling variadic macros.
1 
1    This implementation removes all comments from macro arguments, unless
1 the '-C' option is given.  The form of all other horizontal whitespace
1 in arguments is preserved, including leading and trailing whitespace.
1 In particular
1 
1      f( )
1 
1 is treated as an invocation of the macro 'f' with a single argument
1 consisting of a single space.  If you want to invoke a function-like
1 macro that takes no arguments, you must not leave any whitespace between
1 the parentheses.
1 
1    If a macro argument crosses a new line, the new line is replaced with
1 a space when forming the argument.  If the previous line contained an
1 unterminated quote, the following line inherits the quoted state.
1 
1    Traditional preprocessors replace parameters in the replacement text
1 with their arguments regardless of whether the parameters are within
1 quotes or not.  This provides a way to stringize arguments.  For example
1 
1      #define str(x) "x"
1      str(/* A comment */some text )
1           ==> "some text "
1 
1 Note that the comment is removed, but that the trailing space is
1 preserved.  Here is an example of using a comment to effect token
1 pasting.
1 
1      #define suffix(x) foo_/**/x
1      suffix(bar)
1           ==> foo_bar
1