Пространства имён
Варианты
Действия

Препроцессор

Материал из cppreference.com
< cpp
 
 
Язык С++
Общие темы
Препроцессор
Комментарии
Управление потоком
Операторы условного выполнения
if
Операторы итерации (циклы)
Операторы перехода
Функции
Объявление функции
Выражение лямбда-функции
Спецификатор inline
Спецификации динамических исключений (до C++17*)
Спецификатор noexcept (C++11)
Исключения
Пространства имён
Типы
Спецификаторы
decltype (C++11)
auto (C++11)
alignas (C++11)
Спецификаторы длительности хранения
Инициализация
Выражения
Альтернативные представления
Литералы
Логические - Целочисленные - С плавающей запятой
Символьные - Строковые - nullptr (C++11)
Определяемые пользователем (C++11)
Утилиты
Атрибуты (C++11)
Types
Объявление typedef
Объявление псевдонима типа (C++11)
Casts
Неявные преобразования - Явные преобразования
static_cast - dynamic_cast
const_cast - reinterpret_cast
Выделение памя��и
Классы
Свойства функции класса
explicit (C++11)
static
Специальные функции-элементы
Шаблоны
Разное
 
 

Препроцессор выполняется во время выполнения фазы трансляции 4, перед компиляцией. Результатом препроцессинга является единственный файл, который затем передаётся фактическому компилятору.

Содержание

[править] Директивы

Препроцессинговые директивы управляют поведением препроцессора. Каждая директива занимает одну строку и имеет следующий формат:

  • символ #
  • последовательность:
  • стандартное имя директивы (перечисленные ниже), за которым следуют соответствующие аргументы, или
  • один или несколько токенов предварительной обработки, где начальный токен не является стандартным именем директивы, в этом случае директива поддерживается условно с семантикой, определяемой реализацией (например, общее нестандартное расширение это директива #warning, которая выдаёт определяемое пользователем сообщение во время компиляции) (до C++23), или
  • ничего, в этом случае директива ничего не делает.
  • перевод строки

Директивы module и import также являются директивами препроцесснинга.

(начиная с C++20)

Директивы препроцессинга не должны исходить из раскрытия макроса.

#define EMPTY
EMPTY   #   include <file.h> // не директива препроцессинга

[править] Возможности

Препроцессор обладает следующими возможностями трансляции исходного файла:

  • условная компиляция частей исходного файла (контролируется директивами #if, #ifdef, #ifndef, #else, #elif, #elifdef, #elifndef (начиная с C++23) и #endif)
  • замена текстовых макросов с возможностью конкатенации и заключения в кавычки идентификаторов (контролируется директивами #define и #undef и операторами # и ##)
  • включение других файлов (контролируется директивой #include и проверяется __has_include (начиная с C++17))
  • вызов ошибки или предупреждения (начиная с C++23) (контролируется директивой #error или #warning соответственно (начиная с C++23))

Можно управлять следующими аспектами препроцессора:

[править] Отчёты о дефектах

Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:

Номер Применён Поведение в стандарте Корректное поведение
CWG 2001 C++98 поведение при использовании нестандартно определённых
директив было неясным
сделано условно поддерживаемым

[править] Смотрите также

Документация C++ по Предопределённые Макро Символы
Документация C++ по Указатель Макро Символов
Документация C по препроцессора