实现定义的行为控制
实现定义的行为受 #pragma
指令控制。
语法
#pragma 语用形参
|
(1) | ||||||||
_Pragma( 字符串字面量 )
|
(2) | (C++11 起) | |||||||
L
前缀(如果存在),外层引号,及前导/尾随空白符,将每个 \"
替换为 "
、将每个 \\
替换为 \
,然后将结果记号化(像翻译阶段 3 中一样),再如同将结果作为 (1) 中的输入来使用。解释
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
之一。
ON
。+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 使得,不会错误地在多个文件中使用相同的宏名。另一方面,因为带 #pragma once 的文件是基于其文件系统层次的身份所排除的,所以若头文件在项目中多处出现,则不可避免地再次包含它。
#pragma pack
此 pragma 族控制后继定义的类和联合体的最大对齐。
#pragma pack(实参)
|
(1) | ||||||||
#pragma pack()
|
(2) | ||||||||
#pragma pack(push)
|
(3) | ||||||||
#pragma pack(push, 实参)
|
(4) | ||||||||
#pragma pack(pop)
|
(5) | ||||||||
其中 arg 实参是小的 2 的幂,指定以字节计的新对齐。
#pragma pack 可以指定类的对齐,然而它不能使类过对齐。
本节未完成 原因:解释此语用在数据成员的效果还有使用它们的优势与劣势。参考源: |
本节未完成 原因:暂无示例 |
外部链接
- Visual Studio 的 C++ pragma
- GCC 接受的 Pragma
- IBM AIX XL C 16.1 的单独 pragma 描述及标准 pragma
- Sun Studio 11 C++ 用户指南中的 Appendix B. Pragmas
- Intel C++ compiler pragmas
- HP aCC A.06.25 的发行注记(包括 pragma)