Я читаю Стандарт N1570 о замене макросов и неправильно понимаю некоторые формулировки из 6.10.3.4
.
1 После того, как все параметры в списке замены были заменены
и обработаны # и ##, вся предварительная обработка меток
токены удалены Результирующая последовательность токена предварительной обработки затем
повторно сканируется вместе со всеми последующими токенами предварительной обработки
исходный файл, для дополнительных имен макросов, чтобы заменить
Итак, после того, как все #
и ##
разрешены, мы повторно сканируем список замены. Но в разделе 2 указано:
2 Если имя заменяемого макроса найдено во время этого сканирования
список замены (не включая остальную часть исходного файла
предварительная обработка токенов), он не заменяется. Кроме того, если любой вложенный
замены встречаются с именем заменяемого макроса, это не
заменен.
Это выглядит противоречиво для меня. Итак, какая замена возможна в этом повторном сканировании? Я попробовал следующий пример:
#define FOOBAR(a, b) printf(#a #b)
#define INVOKE(a, b) a##b(a, b)
int main() {
INVOKE(FOO, BAR); //expands to printf("FOO" "BAR")
}
Таким образом, INVOKE(FOO, BAR)
расширяется до FOOBAR(FOO, BAR)
после замены ##
. Затем список замены FOOBAR(FOO, BAR)
повторно сканируется. Но в разделе 2.
указано, что имя заменяемого макроса (FOOBAR
) найдено (да, определено выше), но не заменено (но фактически заменено, как это видно в демонстрационном примере).
Не могли бы вы уточнить эту формулировку? Что я пропустил?
LIVE DEMO