9 Вывод препроцессора
При использовании C-препроцессора с компиляторами C, C++ или Objective-C, он интегрирован в компилятор и передает поток двоичных токенов напрямую в анализатор компилятора. Однако его также можно использовать в более традиционном автономном режиме, где он производит текстовый вывод.
Вывод C-препроцессора выглядит очень похоже на вход, за исключением того, что все строки директив препроцессинга заменены пустыми строками, а все комментарии — пробелами. Длинные последовательности пустых строк отбрасываются.
Стандарт ISO определяет, что реализация определяет, сохраняет ли препроцессор пробелы между токенами или заменяет их, например, одним пробелом. В GNU CPP пробелы между токенами сводятся к одному пробелу, за исключением того, что первый токен в строке, не являющейся директивой, предваряется достаточным количеством пробелов, чтобы он отображался в том же столбце в преобразованном выводе, что и в исходном исходном файле. Это делается для удобства чтения вывода. См. Различия с предыдущими версиями. CPP не вставляет пробелы, где их не было в исходном коде, кроме случаев, когда это необходимо для предотвращения случайного склеивания токенов.
Информация об имени и номере строки исходного файла передается строками следующего вида
# linenum filename flags
Они называются маркёрами строк. Они вставляются по мере необходимости в вывод (но никогда не внутри строки или символьного константа). Они означают, что следующая строка происходит из файла filename на строке linenum. filename никогда не будет содержать непечатаемых символов; они заменяются восьмеричными последовательностями escape.
После имени файла следует ноль или более флагов, которые являются ‘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-4.9.4/cpp/Preprocessor-Output.html