[cpp.subst]

# 15 Preprocessing directives [[cpp]](./#cpp)

## 15.7 Macro replacement [[cpp.replace]](cpp.replace#cpp.subst)

### 15.7.2 Argument substitution [cpp.subst]

[va-opt-replacement:](#nt:va-opt-replacement "15.7.2 Argument substitution [cpp.subst]")  
__VA_OPT__ ( [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1 Preamble [cpp.pre]")opt )

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1670)

After the arguments for the invocation of a function-like macro have
been identified, argument substitution takes place[.](#1.sentence-1)

For each parameter in the replacement list that is neither
preceded by a # or ## preprocessing token nor
followed by a ## preprocessing token, the preprocessing tokens
naming the parameter are replaced by a preprocessing token sequence determined as follows:

- [(1.1)](#1.1)

  If the parameter is of the form [*va-opt-replacement*](#nt:va-opt-replacement "15.7.2 Argument substitution [cpp.subst]"),
 the replacement preprocessing tokens are the
 preprocessing token sequence for the corresponding argument,
 as specified below[.](#1.1.sentence-1)

- [(1.2)](#1.2)

  Otherwise, the replacement preprocessing tokens are the
 preprocessing tokens of corresponding argument after all
 macros contained therein have been expanded[.](#1.2.sentence-1)
  The argument's
 preprocessing tokens are completely macro replaced before
 being substituted as if they formed the rest of the preprocessing
 translation unit with no other preprocessing tokens being available[.](#1.2.sentence-2)

[*Example [1](#example-1)*: #define LPAREN() (#define G(Q) 42#define F(R, X, ...) __VA_OPT__(G R X) )int x = F(LPAREN(), 0, <:-); // replaced by int x = 42; â *end example*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1700)

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[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1706)

[*Example [2](#example-2)*:

#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 infprintf(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));

â *end example*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1726)

The identifier __VA_OPT__ shall always occur as part of the preprocessing token sequence[*va-opt-replacement*](#nt:va-opt-replacement "15.7.2 Argument substitution [cpp.subst]");
its closing ) is determined by skipping
intervening pairs of matching left and right parentheses
in its [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1 Preamble [cpp.pre]")[.](#4.sentence-1)

The [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1 Preamble [cpp.pre]") of a [*va-opt-replacement*](#nt:va-opt-replacement "15.7.2 Argument substitution [cpp.subst]") shall not contain __VA_OPT__[.](#4.sentence-2)

If the [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1 Preamble [cpp.pre]") would be ill-formed
as the replacement list of the current function-like macro,
the program is ill-formed[.](#4.sentence-3)

A [*va-opt-replacement*](#nt:va-opt-replacement "15.7.2 Argument substitution [cpp.subst]") is treated as if it were a parameter,
and the preprocessing token sequence for the corresponding
argument is defined as follows[.](#4.sentence-4)

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.concat "15.7.4 The ## operator"), [[cpp.rescan]](cpp.rescan "15.7.5 Rescanning and further replacement"))[.](#4.sentence-5)

Otherwise, the argument consists of
the results of the expansion of the contained [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1 Preamble [cpp.pre]") as the replacement list of the current function-like macro
before removal of placemarker tokens, rescanning, and further replacement[.](#4.sentence-6)

[*Note [1](#note-1)*:

The placemarker tokens are removed before stringization ([[cpp.stringize]](cpp.stringize "15.7.3 The # operator")),
and can be removed by rescanning and further replacement ([[cpp.rescan]](cpp.rescan "15.7.5 Rescanning and further replacement"))[.](#4.sentence-7)

â *end note*]

[*Example [3](#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) // replaced by f(0, a, b, c) F() // replaced by f(0) F(EMP) // 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__ // error: ## may not appear at// the beginning of a replacement list ([[cpp.concat]](cpp.concat "15.7.4 The ## operator"))#define H2(X, Y, ...) __VA_OPT__(X ## Y,) __VA_ARGS__
H2(a, b, c, d) // replaced by ab, c, d#define H3(X, ...) #__VA_OPT__(X##X X##X) H3(, 0) // replaced by ""#define H4(X, ...) __VA_OPT__(a X ## X) ## b
H4(, 1) // replaced by a b#define H5A(...) __VA_OPT__()/**/__VA_OPT__()#define H5B(X) a ## X ## b#define H5C(X) H5B(X) H5C(H5A()) // replaced by ab â *end example*]
