实现定义行为控制
来自cppreference.com
< cpp | preprocessor
由 #pragma
指令控制实现定义行为。
目录 |
[编辑] 语法
#pragma 语用形参
|
(1) | ||||||||
_Pragma ( 字符串字面量 )
|
(2) | (C++11 起) | |||||||
1) 以实现定义方式表现
2) 从 字符串字面量 移除
L
前缀(若存在)、外层引号,及前导/尾随空白符,将每个 \"
以 "
、每个 \\
以 \
替换,然后记号化结果(如翻译阶段 3 中一样),再如同在 (1) 中输出结果到 #pragma
一样使用结果。[编辑] 解释
pragma 指令控制编译器的实现指定行为,如禁用编译器警告或更改对齐要求。忽略任何不能识别的语用。
[编辑] 非标准语用
ISO C++ 语言标准并不要求编译器支持任何语用。不过,多种实现都支持几种非标准的语用:
[编辑] #pragma STDC
ISO C 语言标准要求 C 编译器支持下列三种语用,一些 C++ 编译器供应商在它们的 C++ 前端中以不同的程度支持它们:
#pragma STDC FENV_ACCESS 实参
|
(1) | ||||||||
#pragma STDC FP_CONTRACT 实参
|
(2) | ||||||||
#pragma STDC CX_LIMITED_RANGE 实参
|
(3) | ||||||||
其中 实参 是 ON
、 OFF
和 DEFAULT
之一。
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
) ,及 |x+iy| = √x2
+y2
,不考虑中间溢出的可能性。换言之,程序员保证传递给这些函数的值范围是受限的。默认值为
+v2
) ,及 |x+iy| = √x2
+y2
,不考虑中间溢出的可能性。换言之,程序员保证传递给这些函数的值范围是受限的。默认值为
OFF
。上述三种语用的任一者都于必须出现于外部声明,或复合语句内任何显式声明和语句之前的语境中,否则行为未定义。
注意:不支持这些 pragma 的编译器可能提供等价的编译时选项,例如 gcc 的 -fcx-limited-range
和 -ffp-contract
。
[编辑] #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
本节未完成 |
[编辑] 参阅
实现定义行为控制 的 C 文档
|
[编辑] 外部链接
- Visual Studio 2015 中的 C++ pragma
- GCC 4.9.2 所接受的 Pragma
- IBM AIX XL C 13.1 中的单独 pragma 描述和标准 pragma
- Sun Studio 11 C++ 用户指导中的 Appendix B. Pragmas
- Intel C++ compiler pragmas 版本 17.0
- HP aCC A.06.25 的释放结点(包括语用)