Управление поведением, определяемым реализацией
Поведение, определяемое реализацией, контролируется директивой #pragma.
Синтаксис
#pragma pragma_params | (1) | |
_Pragma ( строковая_литераль ) | (2) | (с C99) |
\" на " и каждый \\ на \, затем токенизирует результат (как в этапе трансляции 3), и затем использует результат как вход для #pragma в (1).Объяснение
Директива pragma управляет поведением компилятора, специфичным для реализации, например, отключает предупреждения компилятора или изменяет требования к выравниванию. Любая не распознанная директива игнорируется.
Стандартные директивы
Следующие три директивы определены стандартом языка:
#pragma STDC FENV_ACCESS arg | (1) | (с C99) |
#pragma STDC FP_CONTRACT arg | (2) | (с C99) |
#pragma STDC CX_LIMITED_RANGE arg | (3) | (с C99) |
где arg это либо ON, либо OFF, либо DEFAULT.
ON, информирует компилятор, что программа будет обращаться к среде обработки чисел с плавающей точкой или изменять её, что означает, что оптимизации, которые могут нарушить проверки флагов и изменения режимов (например, глобальная оптимизация общих подвыражений, перемещение кода и упрощение констант), запрещены. Значение по умолчанию - определяемое реализацией, обычно OFF. (x * y) + z с помощью одной инструкции процессора fused multiply-add. Значение по умолчанию - определяемое реализацией, обычно ON. OFF. Примечание: компиляторы, не поддерживающие эти директивы, могут предоставить эквивалентные параметры компиляции, такие как -fcx-limited-range и -ffp-contract GCC.
Нестандартные директивы
#pragma once
#pragma once - это нестандартная директива, поддерживаемая подавляющим большинством современных компиляторов. Если она встречается в файле заголовка, она указывает, что она должна быть обработана только один раз, даже если она (прямо или косвенно) включается несколько раз в том же исходном файле.
Стандартный подход к предотвращению многократного включения одного и того же файла заголовков заключается в использовании защит включения:
#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 pack
Этот набор директив управляет максимальным выравниванием для последующих членов структуры и объединения.
#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.
Ссылки
- Стандарт C17 (ISO/IEC 9899:2018):
- 6.10.6 Директива pragma (с. 127)
- 6.10.9 Оператор pragma (с. 129)
- Стандарт C11 (ISO/IEC 9899:2011):
- 6.10.6 Директива pragma (с. 174)
- 6.10.9 Оператор pragma (с. 178)
- Стандарт C99 (ISO/IEC 9899:1999):
- 6.10.6 Директива pragma (с. 159)
- 6.10.9 Оператор pragma (с. 161-162)
- Стандарт C89/C90 (ISO/IEC 9899:1990):
- 3.8.6 Директива pragma
См. также
| Документация C++ для Управление поведением, определяемым реализацией |
Внешние ссылки
| 1. | Директивы pragma в Visual Studio 2019 |
| 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 компилятора |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/preprocessor/impl