Управление поведением, определяемым реализацией
Поведение, определяемое реализацией, контролируется директивой #pragma.
Синтаксис
#pragma pragma-params | (1) | |
_Pragma( string-literal ) | (2) | (начиная с C++11) |
L (если он есть), внешние кавычки и начальные/конечные пробельные символы из string-literal, заменяет каждое \" на " и каждое \\ на \, затем токенизирует результат (как на этапе трансляции 3) и использует полученный результат так, как если бы он был входными данными для #pragma из (1).Пояснение
Директива pragma управляет поведением компилятора, зависящим от реализации, например отключает предупреждения компилятора или изменяет требования к выравниванию. Любая нераспознанная pragma игнорируется.
Нестандартные pragma
Стандарт языка ISO C++ не требует от компиляторов поддержки каких-либо pragma. Однако несколько нестандартных pragma поддерживаются многими реализациями:
#pragma STDC
Стандарт языка ISO C требует, чтобы компиляторы C поддерживали следующие три pragma. Некоторые производители компиляторов C++ поддерживают их в своих интерфейсных частях C++ в разной степени:
#pragma STDC FENV_ACCESS arg | (1) | |
#pragma STDC FP_CONTRACT arg | (2) | |
#pragma STDC CX_LIMITED_RANGE arg | (3) |
где arg — это ON, OFF или DEFAULT.
ON, сообщает компилятору, что программа будет обращаться к среде вычислений с плавающей точкой или изменять её. Это означает, что оптимизации, которые могут помешать проверке флагов и изменению режимов (например, глобальное устранение общих подвыражений, перемещение кода и свёртка констант), запрещены. Значение по умолчанию определяется реализацией, обычно это OFF.(x * y) + z одной инструкцией ЦП fused multiply-add. Значение по умолчанию определяется реализацией, обычно это ON.OFF. Поведение программы не определено, если любая из трёх указанных выше pragma появляется в контексте, отличном от расположения вне всех внешних объявлений или перед всеми явными объявлениями и инструкциями внутри составного оператора.
Примечание: компиляторы, не поддерживающие эти pragma, могут предоставлять эквивалентные параметры компиляции, например -fcx-limited-range и -ffp-contract в gcc.
#pragma once
#pragma once — нестандартная pragma, поддерживаемая подавляющим большинством современных компиляторов. Если она указана в заголовочном файле, это означает, что файл следует анализировать только один раз, даже если он (непосредственно или косвенно) включается несколько раз в один исходный файл.
Стандартный способ предотвратить многократное включение одного и того же заголовка — использовать защиту от повторного включения:
#ifndef LIBRARY_FILENAME_H #define LIBRARY_FILENAME_H // contents of the header #endif /* LIBRARY_FILENAME_H */
Таким образом, при компиляции любой единицы трансляции все включения заголовка, кроме первого, исключаются. Все современные компиляторы запоминают, что в заголовочном файле используется защита от повторного включения, и не анализируют файл повторно, если он встречается снова, пока макрос защиты всё ещё определён (см., например, gcc).
С #pragma once тот же заголовок выглядит так:
#pragma once // contents of the header
В отличие от защиты заголовков, эта 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) |
где arg — небольшая степень двойки, задающая новое выравнивание в байтах.
#pragma pack может уменьшить выравнивание класса, но не может задать для него чрезмерное выравнивание.
См. также сведения о GCC и MSVC.
Ссылки
- Стандарт C++23 (ISO/IEC 14882:2024):
- 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 в C++ в Visual Studio |
| 2. | Pragma, поддерживаемые GCC |
| 3. | Описания отдельных pragma и стандартные pragma в IBM AIX XL C 16.1 |
| 4. | Приложение B. Pragma в руководстве пользователя Sun Studio 11 C++ |
| 5. | Pragma компилятора Intel C++ |
| 6. | Примечания к выпуску (включая pragma) для HP aCC A.06.25 |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/preprocessor/impl