由实现定义的行为控制
行为由 ... 控制
语法
1 | #pragma | pragma-params | |
2 | _Pragma | string-literal |
- 以由实现定义的方式运行。
- 删除 string-literal 的 L 前缀(如果存在)、外部引号以及前导/尾随空格,将每个
\"
替换为"
,将每个\\
替换为\
,然后对结果进行标记(如翻译阶段 3),然后将其结果用作 (1) 中 #pragma 的输入。
非标准 pragmas
ISO C++ 语言标准不要求编译器支持任何 pragmas。然而,许多非标准的 pragmas 被多个实现所支持。
#pragma STDC
ISO C 语言标准要求 C 编译器支持以下三个 pragmas,并且一些 C++ 编译器厂商在其 C++ 前端以不同程度支持它们。
1 | #pragma | STDC | FENV_ACCESS | arg | |
2 | #pragma | STDC | FP_CONTRACT | arg | |
3 | #pragma | STDC | CX_LIMITED_RANGE | arg |
其中 arg 是 ON、OFF 或 DEFAULT。
- 如果设置为 ON,则告知编译器程序将访问或修改浮点环境,这意味着禁止可能破坏标志测试和模式更改的优化(例如,全局公共子表达式消除、代码移动和常量折叠)。默认值为由实现定义,通常为 OFF。
- 允许对浮点表达式进行*收缩*,即忽略舍入错误和浮点异常的优化,而这些错误和异常在表达式按原样精确求值时会被观察到。例如,允许使用单个融合乘加 CPU 指令来实现
(x * y) + z
。默认值为由实现定义,通常为 ON。 - 告知编译器,复数乘法、除法和绝对值可能使用简化的数学公式
(x+iy)×(u+iv) = (xu-yv)+i(yu+xv)
、(x+iy)/(u+iv) = [(xu+yv)+i(yu-xv)]/(u2+v2)
和|x+iy| = √x2+y2
,尽管可能存在中间溢出。换句话说,程序员保证传递给这些函数的参数值的范围是有限的。默认值为 OFF。
#pragma once
防止同一头文件被多次包含的标准方法是使用包含守卫。
#ifndef LIBRARY_FILENAME_H
#define LIBRARY_FILENAME_H
// contents of the header
#endif /* LIBRARY_FILENAME_H */
这样,在任何翻译单元中,除第一次包含头文件外,其余的包含都将被排除在编译之外。所有现代编译器都会记录头文件使用包含守卫的事实,并且当再次遇到它时,只要守卫仍然被定义,就不会重新解析该文件(例如,参见gcc)。
使用
#pragma once
// contents of the header
与包含守卫不同,此 pragma 使得在多个文件中错误地使用相同的宏名称成为不可能。另一方面,因为使用
#pragma pack
这一系列 pragmas 控制后续定义的类和联合成员的最大对齐方式。
1 | #pragma | pack ( arg ) | |
2 | #pragma | pack ( ) | |
3 | #pragma | pack ( push ) | |
4 | #pragma | pack ( push, arg) | |
5 | #pragma | pack ( pop ) |
其中 arg 是 2 的幂,表示新的对齐字节数。
- 将当前对齐方式设置为值 arg。
- 将当前对齐方式设置为默认值(通过命令行选项指定)。
- 将当前对齐方式的值推送到内部堆栈。
- 将当前对齐方式的值推送到内部堆栈,然后将当前对齐方式设置为值 arg。
- 弹出内部堆栈的顶部条目,然后将当前对齐方式设置为(恢复为)该值。
本节不完整 原因:解释此 pragmas 对数据成员的影响以及使用它们的优点和缺点。参考来源
本节不完整 原因:无示例
参考文献
- 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]