实现定义的行为控制
实现定义的行为由 #pragma 指令控制。
内容 |
[编辑] 语法
#pragma pragma-params |
(1) | ||||||||
_Pragma( string-literal ) |
(2) | (自 C++11 起) | |||||||
L
前缀(如果有)、外部引号和前导/尾随空格,用 " 替换每个 \",用 \\ 替换每个 \\,然后对结果进行标记化(如 翻译阶段 3 所述),然后使用结果,就好像它是 (1) 中 #pragma 的输入一样。[编辑] 解释
Pragma 指令控制编译器的实现特定行为,例如禁用编译器警告或更改对齐要求。任何未识别的预处理指令都会被忽略。
[编辑] 非标准预处理指令
ISO C++ 语言标准不要求编译器支持任何预处理指令。但是,多个实现支持一些非标准预处理指令。
[编辑] #pragma STDC
ISO C 语言标准要求 C 编译器支持以下三个预处理指令,并且一些 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
。ON
。+v2
) 和 |x+iy| = √x2
+y2
,即使可能发生中间溢出。换句话说,程序员保证传递给这些函数的值范围有限。默认值为
OFF
。如果以上三个编译指示符出现在除外部声明之外的任何上下文或复合语句中的所有显式声明和语句之前,程序的行为是未定义的。
注意:不支持这些编译指示符的编译器可能会提供等效的编译时选项,例如 gcc 的 -fcx-limited-range
和 -ffp-contract
。
[编辑] #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 once 文件是根据它们的文件系统级标识被排除的,因此如果一个头文件在项目中的多个位置存在,它不能防止多次包含该头文件。
[编辑] #pragma pack
这一系列编译指示符控制随后定义的类和联合成员的最大对齐方式。
#pragma pack(arg)
|
(1) | ||||||||
#pragma pack()
|
(2) | ||||||||
#pragma pack(push)
|
(3) | ||||||||
#pragma pack(push, arg)
|
(4) | ||||||||
#pragma pack(pop)
|
(5) | ||||||||
其中 arg 是一个小的 2 的幂,并指定新的对齐方式(以字节为单位)。
#pragma pack 可以减少类的对齐方式,但是它不能使类过度对齐。
本节内容不完整 原因:解释这些编译指示符对数据成员的影响,以及使用它们的优缺点。参考来源 |
本节内容不完整 原因:没有例子 |
[编辑] 参考资料
- C++23 标准(ISO/IEC 14882:2024)
- 15.9 编译指示符 [cpp.pragma]
- C++20 标准(ISO/IEC 14882:2020)
- 15.9 编译指示符 [cpp.pragma]
- C++17 标准(ISO/IEC 14882:2017)
- 19.6 编译指示符 [cpp.pragma]
- C++14 标准(ISO/IEC 14882:2014)
- 16.6 编译指示符 [cpp.pragma]
- C++11 标准(ISO/IEC 14882:2011)
- 16.6 编译指示符 [cpp.pragma]
- C++98 标准(ISO/IEC 14882:1998)
- 16.6 编译指示符 [cpp.pragma]
[编辑] 另请参见
C 文档 针对 实现定义的行为控制
|
[编辑] 外部链接
1. | Visual Studio 中的 C++ 编译指示符 |
2. | GCC 接受的编译指示符 |
3. | 单个编译指示符描述 和 标准编译指示符 在 IBM AIX XL C 16.1 中 |
4. | 附录 B. 编译指示符 在 Sun Studio 11 C++ 用户指南中 |
5. | 英特尔 C++ 编译器编译指示符 |
6. | 发布节点(包括编译指示符) 针对 HP aCC A.06.25 |