Управление поведением, определённым реализацией
Поведение, определённое реализацией, контролируется директивой #pragma.
Синтаксис
#pragma pragma-params | (1) | |
_Pragma( строковая_литераль ) | (2) | (с C++11) |
L (если он есть), внешние кавычки и начальные/конечные пробелы из строковая_литераль, заменяет каждый \" на " и каждый \\ на \, затем токенизирует результат (как в фазе трансляции 3), а затем использует результат как вход для #pragma в (1).Объяснение
Директива pragma управляет поведением компилятора, специфичным для реализации, например, отключением предупреждений компилятора или изменением требований к выравниванию. Любая не распознанная директива pragma игнорируется.
Нестандартные pragmas
Стандарт языка C++ ISO не требует от компиляторов поддержки каких-либо pragmas. Однако несколько нестандартных pragmas поддерживаются множеством реализаций:
#pragma STDC
Стандарт языка C ISO требует, чтобы компиляторы C поддерживали следующие три pragmas, а некоторые поставщики компиляторов C++ поддерживают их в своих фронтендах для C++ в различной степени:
#pragma STDC FENV_ACCESS аргумент | (1) | |
#pragma STDC FP_CONTRACT аргумент | (2) | |
#pragma STDC CX_LIMITED_RANGE аргумент | (3) |
где аргумент может быть ON, OFF, или DEFAULT.
ON, сообщает компилятору, что программа будет обращаться к среде с плавающей точкой или изменять её, что означает, что оптимизации, которые могут нарушить проверки флагов и изменения режимов (например, глобальная элиминация общих подвыражений, перемещение кода и свёртка констант) запрещены. Значение по умолчанию зависит от реализации, обычно OFF.(x * y) + z с помощью одной инструкции процессора fused multiply-add. Значение по умолчанию зависит от реализации, обычно ON.OFF.Поведение программы неопределено, если любая из трёх pragmas выше появляется в любом контексте, кроме как вне всех внешних деклараций или перед всеми явными декларациями и операторами внутри составного оператора.
Примечание: компиляторы, которые не поддерживают эти pragmas, могут предоставить эквивалентные параметры времени компиляции, такие как -fcx-limited-range и -ffp-contract gcc.
#pragma once
#pragma once — нестандартная директива pragma, которая поддерживается большинством современных компиляторов. Если она появляется в файле заголовка, это указывает на то, что она должна обрабатываться только один раз, даже если она (прямо или косвенно) включается несколько раз в одном файле исходного кода.
Стандартный подход к предотвращению многократного включения одного и того же заголовка — использование include guard:
#ifndef LIBRARY_FILENAME_H #define LIBRARY_FILENAME_H // contents of the header #endif /* LIBRARY_FILENAME_H */
Чтобы все, кроме первого включения заголовка в любой единице трансляции, были исключены из компиляции. Все современные компиляторы записывают тот факт, что файл заголовка использует include guard, и не перекомпилируют файл, если он встречается снова, при условии, что guard всё ещё определён (см., например, gcc).
С #pragma once, тот же самый заголовок выглядит как
#pragma once // contents of the header
В отличие от include guard, эта директива pragma делает невозможным ошибочное использование одного и того же имени макроса более чем в одном файле. С другой стороны, так как с #pragma once файлы исключаются на основе их идентификатора на уровне файловой системы, это не защищает от включения заголовка дважды, если он существует в более чем одном месте в проекте.
#pragma pack
Эта группа директив pragma контролирует максимальное выравнивание для последующих членов класса и объединения.
#pragma pack(arg) | (1) | |
#pragma pack() | (2) | |
#pragma pack(push) | (3) | |
#pragma pack(push, arg) | (4) | |
#pragma pack(pop) | (5) |
где аргумент — это малая степень двойки и определяет новое выравнивание в байтах.
#pragma pack может уменьшить выравнивание класса, но не может сделать класс слишком выровненным.
См. также подробные сведения для GCC и MSVC.
Ссылки
- Стандарт C++23 (ISO/IEC 14882:2023):
- 15.9 Директива pragma [cpp.pragma]
- Стандарт C++20 (ISO/IEC 14882:2020):
- 15.9 Директива pragma [cpp.pragma]
- Стандарт C++17 (ISO/IEC 14882:2017):
- 19.6 Директива pragma [cpp.pragma]
- Стандарт C++14 (ISO/IEC 14882:2014):
- 16.6 Директива pragma [cpp.pragma]
- Стандарт C++11 (ISO/IEC 14882:2011):
- 16.6 Директива pragma [cpp.pragma]
- Стандарт C++98 (ISO/IEC 14882:1998):
- 16.6 Директива pragma [cpp.pragma]
См. также
| Документация по C для Управление поведением, определённым реализацией |
Внешние ссылки
| 1. | Директивы pragma в Visual Studio |
| 2. | Директивы pragma, принятые GCC |
| 3. | Описание отдельных pragmas и Стандартные pragmas в IBM AIX XL C 16.1 |
| 4. | Приложение B. Директивы pragma в руководстве пользователя Sun Studio 11 C++ |
| 5. | Директивы pragma Intel C++ компилятора |
| 6. | Ноды выпуска (включают pragmas) для HP aCC A.06.25 |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/preprocessor/impl