Он говорит в С++ std 16.3.4:
Результирующая последовательность токенов предварительной обработки [из замены вызова макроса] повторно сопоставляется со всеми последующими токенами предварительной обработки исходного файла, для получения большего количества имен макросов заменить.
Если имя заменяемого макроса найдено во время этого сканирования списка замены (не включая остальная часть токенов предварительной обработки исходных файлов), он не заменяется.
Кроме того, если любые вложенные замены сталкиваются с именем заменяемого макроса, он не заменяется.
Эти неперемещаемые маркеры предварительной обработки макросов больше не доступны для дальнейшей замены, даже если они позже (повторно) рассматриваются в контекстах в котором этот токен предварительной обработки имени макроса в противном случае был бы заменен.
Что такое замена вложенных макросов?
В частности, рассмотрим:
#define f(x) 1 x
#define g(x) 2 x
g(f)(g)(3)
Я бы ожидал следующего:
g(f)(g)(3) <-- first replacement of g, ok
2 f(g)(3) <-- nested replacement of f, ok
2 1 g(3) <-- second nested replacement of g, don't replace, stop
Однако gcc неожиданно продолжает вторую замену g, создавая:
2 1 2 3
Любые идеи?
Update:
После долгих исследований позвольте мне прояснить эту проблему с помощью более простого примера:
#define A(x) B
#define B(x) A(x)
A(i)(j)
Это расширяется следующим образом:
A(i)(j)
B(j)
A(j)
В стандарте не указывается, следует ли расширять A(j)
до B
или нет. Комитет решил оставить его таким образом, потому что не предполагается, что программы реального мира будут зависеть от такого поведения, поэтому оба оставшихся A(j)
нерасширенные и расширяющиеся A(j)
до B
считаются совместимыми.