10.1 Традиционный лексический анализ
Традиционный препроцессор не разбивает свой ввод на токены так же, как это делает препроцессор, соответствующий стандарту. Ввод просто обрабатывается как поток текста с минимальной внутренней структурой.
Эта реализация не обрабатывает триграфы (см. триграфы) специально, так как они были изобретением комитета по стандартам. Она корректно обрабатывает произвольно расположенные экранированные символы новой строки и склеивает строки так, как ожидается; многие традиционные препроцессоры этого не делали.
Форма горизонтальных пробелов во входном файле сохраняется в выходном. В частности, жёсткие табуляции остаются жёсткими табуляциями. Это может быть полезно, если, например, вы обрабатываете Makefile.
Традиционный CPP распознаёт только комментарии в стиле C, и рассматривает последовательность «/*» как начало комментария только если она находится вне строковых литералов. Строковые литералы вводятся обычными одиночными и двойными кавычками, а также начальной «<» в директиве #include.
Традиционно комментарии полностью удаляются и не заменяются пробелом. Поскольку традиционный компилятор выполняет свою лексическую обработку выходных данных препроцессора, это означает, что комментарии могут эффективно использоваться как операторы склеивания токенов. Однако комментарии ведут себя как разделители для текста, обрабатываемого самим препроцессором, так как он не пере-лексирует свой ввод. Например, в
#if foo/**/bar
«foo» и «bar» являются различными идентификаторами и расширяются отдельно, если они оказываются макросами. Другими словами, эта директива эквивалентна
#if foo bar
а не
#if foobar
В общем случае в традиционном режиме открывающая кавычка не обязательно должна иметь соответствующую закрывающую кавычку. В частности, макрос может быть определён с текстом замены, содержащим несоответствующую кавычку. Конечно, если вы попытаетесь скомпилировать обработанные данные, содержащие несоответствующую кавычку, вы получите синтаксическую ошибку.
Однако все директивы препроцессинга, кроме #define, требуют соответствия кавычек. Например:
#define m This macro's fine and has an unmatched quote
"/* This is not a comment. */
/* This is a comment. The following #include directive
is ill-formed. */
#include <stdio.h
Как и для ISO препроцессора, закрывающая кавычка может быть экранирована обратным слешем, чтобы предотвратить закрытие строкового литерала.
Далее: Традиционные макросы, Вернуться к: Традиционный режим [Содержание][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-8.5.0/cpp/Traditional-lexical-analysis.html