9 Вывод препроцессора
При использовании C-препроцессора с компиляторами C, C++ или Objective-C, он интегрирован в компилятор и передаёт поток двоичных токенов непосредственно парсеру компилятора. Однако его также можно использовать в более традиционном автономном режиме, где он производит текстовый вывод.
Вывод C-препроцессора выглядит очень похоже на вход, за исключением того, что все строки директив препроцессинга заменены пустыми строками, а все комментарии — пробелами. Длинные серии пустых строк отбрасываются.
Стандарт ISO определяет, что препроцессор сохраняет пробелы между токенами или заменяет их, например, одним пробелом — это определяется реализацией. В GNU CPP пробелы между токенами сводятся к одному пробелу, за исключением первого токена в строке, не являющейся директивой, который предваряется достаточным количеством пробелов, чтобы он отображался в том же столбце в выходных данных препроцессинга, что и в исходном исходном файле. Это делается для удобства чтения выходных данных. См. Различия с предыдущими версиями. CPP не вставляет пробелы там, где их не было в исходном коде, за исключением случаев, когда это необходимо для предотвращения случайного склеивания токенов.
Информация об имени файла и номере строки передаётся строками следующего вида
# linenum filename flags
Они называются маркерами строк. Они вставляются по мере необходимости в вывод (но никогда не внутри строки или символьного литерала). Они означают, что следующая строка происходит из файла filename в строке linenum. filename никогда не будет содержать непечатаемых символов; они заменяются восьмеричными последовательностями экранирования.
После имени файла следует ноль или более флагов, которые являются '1’, ‘2’, ‘3’ или ‘4’. Если флагов несколько, они разделяются пробелами. Вот что означают флаги:
- ‘1’
Это указывает на начало нового файла.
- ‘2’
Это указывает на возврат к файлу (после включения другого файла).
- ‘3’
Это указывает, что следующий текст происходит из системного заголовочного файла, поэтому следует подавлять определённые предупреждения.
- ‘4’
Это указывает, что следующий текст следует рассматривать как заключённый в неявный блок
extern "C".
В качестве расширения, препроцессор принимает маркеры строк в файлах ввода, не являющихся ассемблерными. Они обрабатываются как соответствующая директива ‘#line’ (см. Управление строками), за исключением того, что разрешены флаговые символы, и они интерпретируются в соответствии с описанными выше значениями. Если указано несколько флагов, они должны быть в порядке возрастания.
Некоторые директивы могут дублироваться в выводе препроцессора. Это ‘#ident’ (всегда), ‘#pragma’ (только если препроцессор сам не обрабатывает препроцессорную директиву), а также ‘#define’ и ‘#undef’ (с некоторыми параметрами отладки). Если это происходит, символ ‘#’ директивы всегда будет в первом столбце, и пробел между ‘#’ и именем директивы отсутствовать. Если макрорасширение создаёт токены, которые могут быть ошибочно приняты за дублирующиеся директивы, пробел будет вставлен между ‘#’ и именем директивы.
Далее: Традиционный режим, Предыдущее: Другие директивы, Вверх: Вверх [Оглавление][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-6.5.0/cpp/Preprocessor-Output.html