Document Number: WG14 N581/X3J11 96-045 Variable argument lists for function-like macros Third alternative syntax Notes: this is a further alternative to UK010b. This alternative has *not* been approved by BSI. This sub-proposal is based on an idea by Derek Jones, and I am indebted to Jutta Degener for basic sanity checking. Description ----------- In this alternative syntax, the example would be written: #define printf(...) fprintf(stdout, __VA_ARGS__) Detailed proposal ----------------- In subclause 6.8 Syntax, 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 (this needs to be done with all alternative syntaxes in UK010b). 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 their 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));