19 Preprocessing directives [cpp]

19.3 Macro replacement [cpp.replace]

19.3.3 The ## operator [cpp.concat]

## Предварительная обработка маркера не должны происходить в начале или в конце списка замены для любой формы макроопределения.

Если в списке замены макроса, подобного функции, параметру непосредственно предшествует или следует ## токен предварительной обработки, параметр заменяется последовательностью токенов предварительной обработки соответствующего аргумента; однако, если аргумент не содержит токенов предварительной обработки, вместо этого параметр заменяется токеном предварительной обработки метки места размещения.151

Как для объектно-подобных, так и для функционально-подобных вызовов макросов, прежде чем список замены будет повторно исследован на предмет дополнительных имен макросов для замены, каждый экземпляр ## токена предварительной обработки в списке замены (не из аргумента) удаляется, а предыдущий токен предварительной обработки объединяется со следующим токеном предварительной обработки. Жетоны предварительной обработки меток-меток обрабатываются особым образом: объединение двух меток приводит к одному токену предварительной обработки метки-метки, а объединение метки-метки с токеном предварительной обработки без метки приводит к получению маркера предварительной обработки без метки. Если результат не является допустимым токеном предварительной обработки, поведение не определено. Полученный токен доступен для дальнейшей замены макроса. Порядок оценки ## операторов не указан.

[ Example: В следующем фрагменте:

#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";

Расширение производит на разных этапах:

join(x, y)
in_between(x hash_hash y)
in_between(x ## y)
mkstr(x ## y)
"x ## y"

Другими словами, при раскрытии hash_­hash создается новый токен, состоящий из двух смежных острых знаков, но этот новый токен не является ## оператором. ] end example

Жетоны предварительной обработки меток не отображаются в синтаксисе, поскольку они являются временными объектами, которые существуют только на этапе перевода 4.