Препроцессор
Препроцессор выполняется на фазе трансляции 4, до компиляции. Результатом препроцессирования является единый файл, который затем передаётся непосредственно компилятору.
Директивы
Директивы препроцессирования управляют поведением препроцессора. Каждая директива занимает одну строку и имеет следующий формат:
- символ
#. - последовательность из:
- имени директивы, определённого стандартом (перечислены ниже), за которым следуют соответствующие аргументы, или
- одного или нескольких токенов препроцессирования, где начальный токен не является именем директивы, определённым стандартом; в этом случае директива является условно поддерживаемой с семантикой, определяемой реализацией (например, распространённым нестандартным расширением является директива
#warning, которая выводит пользовательское сообщение во время компиляции)(до C++23), или - ничего; в этом случае директива не оказывает никакого эффекта.
- перевод строки.
| Директивы модуля и импорта также являются директивами препроцессирования. | (начиная с C++20) |
Директивы препроцессирования не должны быть результатом раскрытия макроса.
#define EMPTY EMPTY # include <file.h> // not a preprocessing directive
Возможности
Препроцессор предоставляет следующие возможности преобразования исходного файла:
-
условно компилировать части исходного файла (управляется директивами
#if,#ifdef,#ifndef,#else,#elif,#elifdef,#elifndef(начиная с C++23) и#endif). -
заменять текстовые макросы, при необходимости объединяя или заключая в кавычки идентификаторы (управляется директивами
#defineи#undef, а также операторами#и##). -
включать другие файлы (управляется директивой
#includeи проверяется с помощью__has_include(начиная с C++17)). - вызывать ошибку или предупреждение(начиная с C++23) (управляется директивой
#errorили#warningсоответственно(начиная с C++23)).
Можно управлять следующими аспектами работы препроцессора:
-
поведением, определяемым реализацией (управляется директивой
#pragmaи оператором_Pragma(начиная с C++11)). Кроме того, некоторые компиляторы в разной степени поддерживают оператор__pragmaкак нестандартное расширение. -
имя файла и информацию о строке, доступные препроцессору (управляется директивой
#line).
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.
| Отчёт об ошибке | Применён к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
| CWG 2001 | C++98 | поведение при использовании директив, не определённых стандартом, было неясным | сделано условно поддерживаемым |
См. также
| Документация C++ о предопределённых символах макросов | |
| Документация C++ об индексе символов макросов | |
| Документация C о препроцессоре |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/preprocessor