Контроль поведения, определяемый реализацией
Поведение, определяемое реализацией, контролируется директивой #pragma.
Содержание |
[править]Синтаксис
#pragma параметры-прагмы | (1) | ||||||||
_Pragma ( строковый-литерал) | (2) | (начиная с C++11) | |||||||
L
(если есть) , внешние кавычки и начальные/конечные пробелы из строкового-литерала, заменяет каждый \" на " и каждый \\ на \, затем токенизирует результат (как на стадии трансляции 3), а затем использует результат, как если бы входные данные для #pragma были как в (1)[править]Объяснение
Директива pragma управляет поведением компилятора, зависящим от реализации, например отключением предупреждений компилятора или изменением требований к выравниванию. Любая нераспознанная pragma игнорируется.
[править]Нестандартные прагмы
Стандарт языка ISO C++ не требует, чтобы компиляторы поддерживали какие-либо прагмы. Однако несколько нестандартных прагм поддерживаются несколькими реализациями:
[править]#pragma STDC
Стандарт языка ISO C требует, чтобы компиляторы C поддерживали следующие три прагмы, и некоторые поставщики компиляторов C++ поддерживают их в той или иной степени в своих фронтэндах:
#pragma STDC FENV_ACCESS аргумент | (1) | ||||||||
#pragma STDC FP_CONTRACT аргумент | (2) | ||||||||
#pragma STDC CX_LIMITED_RANGE аргумент | (3) | ||||||||
где аргумент равно ON
, OFF
или DEFAULT
.
ON
, это информирует компилятор о том, что программа будет обращаться или изменять среду с плавающей запятой, что означает, что оптимизации, которые могут нарушить проверку флагов и изменения режима (например, глобальное устранение общих подвыражений, перемещение кода и сворачивание констант) запрещены. Значение по умолчанию определяется реализацией, обычно OFF
.ON
.+v2
) и |x+iy| = √x2
+y2
, несмотря на возможность промежуточного переполнения. Другими словами, программист гарантирует, что диапазон значений, которые будут переданы этой функции, ограничен. Значение по умолчанию
OFF
.Поведение программы не определено, если любая из трёх приведённых выше прагм появляется в любом контексте, кроме вне всех внешних объявлений или перед всеми явными объявлениями и операторами внутри составного оператора.
Примечание: компиляторы, которые не поддерживают эти прагмы, могут предоставлять эквивалентные параметры времени компиляции, такие как -fcx-limited-range
и -ffp-contract
в gcc.
[править]#pragma once
#pragma once нестандартная прагма, которая поддерживается подавляющим большинством современных компиляторов. Если она появляется в заголовочном файле, это означает, что файл должен быть проанализирован только один раз, даже если он (прямо или косвенно) включен несколько раз в один и тот же исходный файл.
Стандартный подход к предотвращению множественного включения одного и того же заголовка заключается в использовании защиты подключения:
#ifndef LIBRARY_FILENAME_H#define LIBRARY_FILENAME_H// содержимое заголовка#endif /* LIBRARY_FILENAME_H */
Так что все, кроме первого включения заголовка в любую единицу трансляции, исключаются из компиляции. Все современные компиляторы фиксируют тот факт, что заголовочный файл использует защиту включения, и не анализируют файл повторно, если он встречается снова, пока защита всё ещё определена. (смотрите, например, gcc)
С #pragma once тот же заголовок отображается как
#pragma once// содержимое заголовка
В отличие от защиты заголовков, эта прагма делает невозможным ошибочное использование одного и того же имени макроса более чем в одном файле. С другой стороны, поскольку с #pragma once файлы исключаются на основе их идентичности на уровне файловой системы, это не может защитить от включения заголовка дважды, если он существует более чем в одном месте в проекте.
[править]#pragma pack
Это семейство прагм управляет максимальным выравниванием для последовательно определенных элементов класса и объединения.
#pragma pack(аргумент) | (1) | ||||||||
#pragma pack() | (2) | ||||||||
#pragma pack(push) | (3) | ||||||||
#pragma pack(push, аргумент) | (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. | Прагмы C++ в Visual Studio 2019 |
2. | Прагмы, принятые GCC |
3. | Индивидуальные описания прагм и Стандартные прагмы в IBM AIX XL C 16.1}} |
4. | Приложение B. Прагмы в Руководстве Пользователя Sun Studio 11 C++ |
5. | Прагмы компилятора Intel C++ |
6. | Выпущенные узлы (включая прагмы) для HP aCC A.06.25 |