[cpp.concat]

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

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

### 15.7.4 The ## operator [cpp.concat]

[1](#1)

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

A## preprocessing token shall not occur at the beginning or
at the end of a replacement list for either form
of macro definition[.](#1.sentence-1)

[2](#2)

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

If, in the replacement list of a function-like macro, a parameter is
immediately preceded or followed by a## preprocessing token, the parameter is replaced by the
corresponding argument's preprocessing token sequence; however, if an argument consists of no preprocessing tokens, the parameter is
replaced by a placemarker preprocessing token instead[.](#2.sentence-1)[128](#footnote-128 "Placemarker preprocessing tokens do not appear in the syntax because they are temporary entities that exist only within translation phase 4.")

[3](#3)

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

For both object-like and function-like macro invocations, before the
replacement list is reexamined for more macro names to replace,
each instance of a## preprocessing token in the replacement list
(not from an argument) is deleted and the
preceding preprocessing token is concatenated
with the following preprocessing token[.](#3.sentence-1)

Placemarker preprocessing tokens are handled specially: concatenation
of two placemarkers results in a single placemarker preprocessing token, and
concatenation of a placemarker with a non-placemarker preprocessing token results
in the non-placemarker preprocessing token[.](#3.sentence-2)

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

Concatenation can form
a [*universal-character-name*](lex.universal.char#nt:universal-character-name "5.3.2 Universal character names [lex.universal.char]") ([[lex.charset]](lex.charset "5.3.1 Character sets"))[.](#3.sentence-3)

â *end note*]

If the result is not a valid preprocessing token,
the program is ill-formed[.](#3.sentence-4)

The resulting preprocessing token is available for further macro replacement[.](#3.sentence-5)

The order of evaluation of## operators is unspecified[.](#3.sentence-6)

[4](#4)

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

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

The sequence#define str(s) # s#define xstr(s) str(s)#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \
 x ## s, x ## t)#define INCFILE(n) vers ## n#define glue(a, b) a ## b#define xglue(a, b) glue(a, b)#define HIGHLOW "hello"#define LOW LOW ", world" debug(1, 2);
fputs(str(strncmp("abc\0d", "abc", '\4') // this goes away== 0) str(: @\n), s);#include xstr(INCFILE(2).h) glue(HIGH, LOW);
xglue(HIGH, LOW) results inprintf("x" "1" "= %d, x" "2" "= %s", x1, x2);
fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n", s);#include "vers2.h" (*after macro replacement, before file access*)"hello";"hello" ", world" or, after concatenation of the character string literals,printf("x1= %d, x2= %s", x1, x2);
fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0: @\n", s);#include "vers2.h" (*after macro replacement, before file access*)"hello";"hello, world"

Space around the # and ## preprocessing tokens in the macro definition
is optional[.](#4.sentence-2)

â *end example*]

[5](#5)

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

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

In the following fragment:#define hash_hash # ## ##define mkstr(a) # a#define in_between(a) mkstr(a)#define join(c, d) in_between(c hash_hash d)char p[] = join(x, y); // equivalent to char p[] = "x ## y";

The expansion produces, at various stages:join(x, y) in_between(x hash_hash y) in_between(x ## y) mkstr(x ## y)"x ## y"

In other words, expanding hash_hash produces a new preprocessing token,
consisting of two adjacent sharp signs, but this new preprocessing token is not the## operator[.](#5.sentence-3)

â *end example*]

[6](#6)

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

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

To illustrate the rules for placemarker preprocessing tokens, the sequence#define t(x,y,z) x ## y ## zint j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
 t(10,,), t(,11,), t(,,12), t(,,) }; results inint j[] = { 123, 45, 67, 89, 10, 11, 12, };

â *end example*]

[128)](#footnote-128)[128)](#footnoteref-128)

Placemarker preprocessing tokens do not appear in the syntax
because they are temporary entities that exist only within translation phase 4[.](#footnote-128.sentence-1)
