[cpp.subst] (original) (raw)

The identifier __VA_OPT__shall always occur as part of the preprocessing token sequenceva-opt-replacement; its closing ) is determined by skipping intervening pairs of matching left and right parentheses in its pp-tokens.

The pp-tokens of a va-opt-replacementshall not contain __VA_OPT__.

If the pp-tokens would be ill-formed as the replacement list of the current function-like macro, the program is ill-formed.

A va-opt-replacement is treated as if it were a parameter, and the preprocessing token sequence for the corresponding argument is defined as follows.

If the substitution of __VA_ARGS__ as neither an operand of # nor ## consists of no preprocessing tokens, the argument consists of a single placemarker preprocessing token ([cpp.concat], [cpp.rescan]).

Otherwise, the argument consists of the results of the expansion of the contained pp-tokensas the replacement list of the current function-like macro before removal of placemarker tokens, rescanning, and further replacement.

[Note 1:

The placemarker tokens are removed before stringization ([cpp.stringize]), and can be removed by rescanning and further replacement ([cpp.rescan]).

— _end note_]

[Example 3: #define F(...) f(0 __VA_OPT__(,) __VA_ARGS__) #define G(X, ...) f(0, X __VA_OPT__(,) __VA_ARGS__) #define SDEF(sname, ...) S sname __VA_OPT__(= { __VA_ARGS__ }) #define EMP F(a, b, c)F()F(EMP)G(a, b, c)G(a, )G(a)SDEF(foo); SDEF(bar, 1, 2); #define H1(X, ...) X __VA_OPT__(##) __VA_ARGS__ #define H2(X, Y, ...) __VA_OPT__(X ## Y,) __VA_ARGS__ H2(a, b, c, d) #define H3(X, ...) #__VA_OPT__(X##X X##X)H3(, 0) #define H4(X, ...) __VA_OPT__(a X ## X) ## b H4(, 1) #define H5A(...) __VA_OPT__()__VA_OPT__() #define H5B(X) a ## X ## b#define H5C(X) H5B(X)H5C(H5A()) — _end example_]