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’ (только если сам препроцессор не обрабатывает пragma), и ‘#define’ и ‘#undef’ (с определенными опциями отладки). Если это произойдет, ‘#’ директивы всегда будет в первой колонке, и пробел между ‘#’ и именем директивы не будет. Если макрорасширение создает токены, которые могут быть ошибочно приняты за дублированную директиву, между ‘#’ и именем директивы будет вставлен пробел.
Далее: Традиционный режим, Предыдущее: Другие директивы, Вверх: В начало [Оглавление][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-8.5.0/cpp/Preprocessor-Output.html