1.4 Язык предварительной обработки ¶
После токенизации поток токенов может быть просто передан непосредственно парсеру компилятора. Однако, если он содержит какие-либо операции на языке предварительной обработки, он будет сначала преобразован. Эта стадия примерно соответствует «фазе перевода 4» стандарта и является тем, что большинство людей имеют в виду под работой препроцессора.
Язык предварительной обработки состоит из директив, которые должны быть выполнены, и макросов, которые должны быть расширены. Его основные возможности:
- Включение файлов заголовков. Это файлы деклараций, которые могут быть подставлены в вашу программу.
- Расширение макросов. Вы можете определить макросы, которые являются сокращениями для произвольных фрагментов кода C. Препроцессор заменит макросы их определениями во всей программе. Некоторые макросы определены для вас автоматически.
- Условный компиляцию. Вы можете включать или исключать части программы в зависимости от различных условий.
- Управление строками. Если вы используете программу для объединения или перестановки исходных файлов в промежуточный файл, который затем компилируется, вы можете использовать управление строками, чтобы сообщить компилятору, откуда взята каждая строка исходного кода.
- Диагностика. Вы можете обнаруживать проблемы во время компиляции и выводить ошибки или предупреждения.
Есть ещё несколько, менее полезных, функций.
За исключением расширения предопределённых макросов, все эти операции запускаются с помощью директивы предварительной обработки. Директивы предварительной обработки — это строки в вашей программе, которые начинаются с ‘#’. Разрешены пробелы до и после ‘#’. За ‘#’ следует идентификатор, имя директивы. Он определяет операцию, которую нужно выполнить. Директивы обычно записываются как ‘#имя’, где имя — это имя директивы. Например, ‘#define’ — это директива, которая определяет макрос.
‘#’, который начинает директиву, не может быть получен из расширения макроса. Также имя директивы не расширяется с помощью макросов. Таким образом, если foo определён как макрос, расширяющийся до define, это не делает ‘#foo’ допустимой директивой предварительной обработки.
Набор допустимых имён директивы фиксирован. Программы не могут определять новые директивы предварительной обработки.
Некоторые директивы требуют аргументов; они составляют остальную часть строки директивы и должны быть разделены от имени директивы пробелами. Например, ‘#define’ должно следовать имя макроса и предназначенное расширение макроса.
Директива предварительной обработки не может охватывать более одной строки. Однако строка может быть продолжена обратным слэшем-новой строкой или блоком комментариев, который простирается за пределы конца строки. В любом случае, при обработке директивы продолжения уже объединены с первой строкой, чтобы образовать одну длинную строку.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-11.4.0/cpp/The-preprocessing-language.html