19 Preprocessing directives [cpp]

19.3 Macro replacement [cpp.replace]

19.3.1 Argument substitution [cpp.subst]

After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place.
A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded.
Before being substituted, each argument's preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.
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.
The identifier __VA_­OPT__ shall always occur as part of the token sequence __VA_­OPT__(content), where content is an arbitrary sequence of preprocessing-tokens other than __VA_­OPT__, which is terminated by the closing ) and skips intervening pairs of matching left and right parentheses.
If content would be ill-formed as the replacement list of the current function-like macro, the program is ill-formed.
The token sequence __VA_­OPT__(content) shall be treated as if it were a parameter, and the preprocessing tokens used to replace it are defined as follows.
If the variable arguments consist of no tokens, the replacement consists of a single placemarker preprocessing token ([cpp.concat], [cpp.rescan]).
Otherwise, the replacement consists of the results of the expansion of content as the replacement list of the current function-like macro before rescanning and further replacement.
[Example
:
#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__ })

F(a, b, c)          // replaced by f(0, a, b, c)
F()                 // replaced by f(0)

G(a, b, c)          // replaced by f(0, a, b, c)
G(a, )              // replaced by f(0, a)
G(a)                // replaced by f(0, a)

SDEF(foo);          // replaced by S foo;
SDEF(bar, 1, 2);    // replaced by S bar = { 1, 2 };

#define H1(X, ...) X __VA_OPT__(##) __VA_ARGS__ // ill-formed: ## may not appear at
                                                // the beginning of a replacement list ([cpp.concat])
#define H2(X, Y, ...) __VA_OPT__(X ## Y,) __VA_ARGS__

H2(a, b, c, d)      // replaced by ab, c, d
end example
]