ISO/ IEC JTC1/SC22/WG14 N707

Document Number:  WG14 N707/J11 97-070


Varargs for function-like macros
================================
Final wording
=============

This is hopefully final wording for this proposal, previously N581 and
discussed at Amsterdam and Toronto.


Detailed proposal
-----------------
In subclause 6.8 Syntax, add two further alternatives to control-line:

  # define identifier lparen ... ) replacement-list new-line
  - ------                   --- -
  # define identifier lparen identifier-list , ... )
  - ------                                   - --- -
                                           replacement-list new-line

(literal tokens are underlined).


Add the same alternatives to the fourth paragraph of the semantics of
6.8.3.


In subclause 6.8.3, replace the constraint:

  The  number  of  arguments  in  an  invocation   of   a
  function-like   macro   shall   agree  with  the  number  of
  parameters in the macro definition, and there shall exist  a
  ) preprocessing token that terminates the invocation.

with

  If the identifer-list in the macro definition does not end with an
  ellipsis, the number of arguments in an invocation of a
  function-like macro shall agree with the number of
  parameters in the macro definition. Otherwise, there shall be more
  arguments in the invocation than there are parameters
  in the macro definition (excluding the ...). There shall exist a
  ) preprocessing token that terminates the invocation.


Add the further constraint:

  The identifier __VA_ARGS__ shall only occur in the replacement-list
  of a #define preprocessing directive using the ellipsis notation
  in the arguments.


Add after the last paragraph of the Semantics:

  If there is a ... in the identifier-list in the macro
  definition, then the trailing arguments, including any
  separating comma preprocessing tokens, are merged to form a
  single item: the /variable arguments/. The number of arguments
  so combined is such that, following merger, the number of arguments
  is one more than the number of parameters in the macro definition
  (excluding the ...).


Add to the end of subclause 6.8.3.1:

  An identifier __VA_ARGS__ that occurs in the replacement list shall
  be treated as if it were a parameter, and the variable arguments
  shall form the preprocessing tokens used to replace it.


In the examples following subclause 6.8.3.5, change the initial text of
example 5 to:

  5. To demonstrate the redefinition rules,

and add a new example 6:

  6. Finally, to show the variable argument list macro facilities:

    #define debug(...)     fprintf(stderr, __VA_ARGS__)
    #define showlist(...)  puts(#__VA_ARGS__)
    #define report(test, ...) ((test) ? puts(#test) : printf (__VA_ARGS__))
    debug("Flag");
    debug("X = %d\n", x);
    showlist(The first, second, and third items.);
    report(x>y, "x is %d but y is %d", x, y);

  results in:

    fprintf(stderr, "Flag");
    fprintf(stderr, "X = %d\n", x);
    puts("The first, second, and third items.");
    ((x>y) ? puts ("x>y") : printf ("x is %d but y is %d", x, y));