#pragma directive
实现定义的行为控制
实现定义的行为由#pragma
指令控制。
句法
#pragma pragma_params | (1) | |
---|---|---|
_Pragma ( string-literal ) | (2) | (since C99) |
1)以实现定义的方式运行(除非 pragma_params 是下面显示的标准编译指示之一。
2)删除字串文本编码前缀(如果有的话),外报价,和前/后空白,替换每个\"
与"
每个\\
带\
,然后标记化的结果(如在翻译阶段3),然后使用该结果作为如果输入到#pragma
(1)中。
说明
编译指示控制编译器的特定于实现的行为,例如禁用编译器警告或更改对齐要求。任何未被识别的杂注将被忽略。
标准杂注
语言标准定义了以下三个编译指示:
#pragma STDC FENV_ACCESS arg | (1) | |
---|---|---|
#pragma STDC FP_CONTRACT arg | (2) | |
#pragma STDC CX_LIMITED_RANGE arg | (3) | |
其中 arg 是任一ON
或OFF
或DEFAULT
。
1)如果设置为ON
,则通知编译器该程序将访问或修改浮点环境,这意味着禁止可能破坏标志测试和模式更改的优化(例如全局公共子表达式消除,代码运动和常量折叠) 。默认值通常是实现定义的OFF
。
2)允许浮点表达式的收缩,即忽略舍入错误和浮点异常的优化,如果表达式完全按照写法进行计算,则可以观察到这些异常。例如,允许(x*y) + z
使用单个融合的乘加 CPU 指令来实现。默认值通常是实现定义的ON
。
3)通知编译器,复数乘法,除法和绝对值可以用简化的数学公式(x + iy)×(u + iv)=(xu-yv)+ i(yu + xv),(x + iy )/(u + iv)=(xu + yv)+ i(yu-xv)/(u2
+v2
), and |x+iy| = √x2
+y2
尽管可能出现中间溢出。换句话说,程序员保证传递给这些函数的值的范围是有限的。默认值是OFF
非标准的编译指示
#pragma once
#pragma once
是绝大多数现代编译器支持的非标准编译指示。如果它出现在头文件中,则表明它只是被解析一次,即使它被(直接或间接)多次包含在同一个源文件中。
标准的方法来防止多个包含相同的标题是通过使用包括守卫:
#ifndef FILENAME_H
#define FILENAME_H
// contents of the header
#endif /* FILENAME_H */
因此,任何翻译单元中除首标头以外的所有内容都不包含在汇编中。
与#pragma once
,相同的标题显示。
#pragma once
// contents of the header
与标头守卫不同,此附注使得不可能在多个文件中错误地使用相同的宏名称。另一方面,由于#pragma once
基于文件系统级别的身份排除文件,如果它存在于项目中的多个位置,则无法防止包含头两次。
#pragma pack
参考
- C11标准(ISO / IEC 9899:2011):