Implementation defined behavior control
Поведение, определяемое реализацией, контролируется с помощью #pragma директивы.
Содержание |
Синтаксис
#pragma
pragma-params
|
(1) | ||||||||
_Pragma(
string-literal
)
|
(2) | (начиная с C++11) | |||||||
L
(если присутствует), внешние кавычки и ведущие/завершающие пробелы из
string-literal
, заменяет каждую
\
"
на
"
и каждую
\\
на
\
, затем токенизирует результат (как в
фазе трансляции 3
), и затем использует результат, как если бы это был ввод для
#pragma
в
(1)
.
Объяснение
Директива Pragma управляет поведением компилятора, специфичным для реализации, таким как отключение предупреждений компилятора или изменение требований к выравниванию. Любая нераспознанная прагма игнорируется.
Нестандартные прагмы
Стандарт языка ISO C++ не требует от компиляторов поддержки каких-либо прагм. Однако несколько нестандартных прагм поддерживаются многими реализациями:
#pragma STDC
Стандарт языка ISO C требует, чтобы компиляторы C поддерживали следующие три прагмы, и некоторые производители компиляторов C++ поддерживают их в разной степени в своих фронтендах для C++:
#pragma STDC FENV_ACCESS
аргумент
|
(1) | ||||||||
#pragma STDC FP_CONTRACT
аргумент
|
(2) | ||||||||
#pragma STDC CX_LIMITED_RANGE
аргумент
|
(3) | ||||||||
где
arg
может быть
ON
,
OFF
или
DEFAULT
.
ON
, информирует компилятор, что программа будет обращаться или изменять
floating-point environment
, что означает, что оптимизации, которые могут нарушать проверки флагов и изменения режимов (например, глобальное устранение общих подвыражений, перемещение кода и свертка констант), запрещены. Значение по умолчанию определяется реализацией, обычно
OFF
.
ON
.
+v 2
) , и |x+iy| = √ x 2
+y 2
, несмотря на возможность промежуточного переполнения. Другими словами, программист гарантирует, что диапазон значений, передаваемых этим функциям, ограничен. Значение по умолчанию —
OFF
.
Поведение программы не определено, если любая из трех приведенных выше прагм появляется в любом контексте, кроме как вне всех внешних объявлений или предшествует всем явным объявлениям и операторам внутри составного оператора.
Примечание: компиляторы, не поддерживающие эти прагмы, могут предоставлять эквивалентные опции времени компиляции, такие как
-fcx-limited-range
и
-ffp-contract
.
#pragma once
#pragma once — это нестандартная прагма, поддерживаемая подавляющим большинством современных компиляторов . Если она появляется в заголовочном файле, это означает, что он должен быть обработан только один раз, даже если он включен (напрямую или косвенно) несколько раз в том же исходном файле.
Стандартный подход для предотвращения многократного включения одного и того же заголовка заключается в использовании include guards :
#ifndef LIBRARY_FILENAME_H #define LIBRARY_FILENAME_H // содержимое заголовочного файла #endif /* LIBRARY_FILENAME_H */
Чтобы все включения заголовочного файла, кроме первого, в любой единице трансляции исключались из компиляции. Все современные компиляторы запоминают факт использования include guard в заголовочном файле и не выполняют повторный разбор файла при повторном его обнаружении, пока guard остается определенным (см., например, gcc ).
С помощью #pragma once тот же заголовок появляется как
#pragma once // содержимое заголовочного файла
В отличие от стражей заголовков, эта директива делает невозможным ошибочное использование одного и того же имени макроса в нескольких файлах. С другой стороны, поскольку с #pragma once файлы исключаются на основе их идентификатора на уровне файловой системы, это не может защитить от двукратного включения заголовка, если он существует в нескольких местах проекта.
#pragma pack
Это семейство прагм управляет максимальным выравниванием для последующих членов классов и объединений.
#pragma pack(
arg
)
|
(1) | ||||||||
#pragma pack()
|
(2) | ||||||||
#pragma pack(push)
|
(3) | ||||||||
#pragma pack(push,
arg
)
|
(4) | ||||||||
#pragma pack(pop)
|
(5) | ||||||||
` и `
` оставлен без изменений, так как содержит C++ специфические термины и директивы препроцессора, которые не подлежат переводу. HTML структура и атрибуты также полностью сохранены.
где 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. | Прагмы C++ в Visual Studio |
| 2. | Прагмы поддерживаемые GCC |
| 3. | Описания отдельных прагм и Стандартные прагмы в IBM AIX XL C 16.1 |
| 4. | Приложение Б. Прагмы в руководстве пользователя Sun Studio 11 C++ |
| 5. | Прагмы компилятора Intel C++ |
| 6. | Узлы выпуска (включая прагмы) для HP aCC A.06.25 |