Implementation defined behavior control
       实现定义的行为由
       
        #pragma
       
       指令控制。
      
| 目录 | 
语法
| 
          
           #pragma
          
         编译指示参数 | (1) | ||||||||
| 
          
           _Pragma
          
         
          
           (
          
         字符串字面量
          
           )
          
          | (2) | (自 C99 起) | |||||||
        \"
       
       替换为
       
        "
       
       、每个
       
        \\
       
       替换为
       
        \
       
       ,随后对结果进行词法分析(如同在
       
        翻译阶段3
       
       中),最终将结果作为
       
        #pragma
       
       的输入,处理方式同
       
        (1)
       
       。
      说明
pragma 指令用于控制编译器的实现特定行为,例如禁用编译器警告或更改对齐要求。任何无法识别的 pragma 都会被忽略。
标准杂注
以下三个编译指令由语言标准定义:
| 
          
           #pragma STDC FENV_ACCESS
          
         参数 | (1) | (C99起) | |||||||
| 
          
           #pragma STDC FP_CONTRACT
          
         参数 | (2) | (C99起) | |||||||
| 
          
           #pragma STDC CX_LIMITED_RANGE
          
         参数 | (3) | (C99起) | |||||||
       其中
       
        arg
       
       可以是
       
        
         ON
        
       
       或
       
        
         OFF
        
       
       或
       
        
         DEFAULT
        
       
       。
      
        
         ON
        
       
       。
      +v 2
) 以及 |x+iy| = √ x 2
+y 2
,即使可能存在中间结果溢出。换言之,程序员需确保传递给这些函数的数值范围是受限的。默认值为
        
         OFF
        
       
       。
      
       注意:不支持这些编译指示的编译器可能提供等效的编译时选项,例如 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
该系列杂注控制后续定义的结构体和联合体成员的最大对齐方式。
| 
          
           #pragma pack(
           
            arg
           
           )
          
          | (1) | ||||||||
| 
          
           #pragma pack()
          
          | (2) | ||||||||
| 
          
           #pragma pack(push)
          
          | (3) | ||||||||
| 
          
           #pragma pack(push,
           
            arg
           
           )
          
          | (4) | ||||||||
| 
          
           #pragma pack(pop)
          
          | (5) | ||||||||
其中 arg 是一个较小的2的幂次方,用于指定以字节为单位的新对齐方式。
#pragma pack 可能会降低结构体的对齐方式,但无法使结构体过度对齐。
| 本节内容不完整 原因:需说明此编译指示对数据成员的影响及其使用的优缺点。参考来源: | 
| 本节内容不完整 原因:缺少示例 | 
参考文献
- C23 标准 (ISO/IEC 9899:2024):
- 
         - 6.10.6 Pragma 指令 (p: TBD)
 
- 
         - 6.10.9 Pragma 运算符 (p: TBD)
 
- C17 标准 (ISO/IEC 9899:2018):
- 
         - 6.10.6 Pragma 指令 (页: 127)
 
- 
         - 6.10.9 Pragma 运算符 (页: 129)
 
- C11 标准 (ISO/IEC 9899:2011):
- 
         - 6.10.6 Pragma 指令 (p: 174)
 
- 
         - 6.10.9 Pragma 运算符 (p: 178)
 
- C99标准(ISO/IEC 9899:1999):
- 
         - 6.10.6 Pragma指令(页码:159)
 
- 
         - 6.10.9 Pragma运算符(页码:161-162)
 
- C89/C90 标准 (ISO/IEC 9899:1990):
- 
         - 3.8.6 Pragma 指令
 
参见
| 
          
           
            C++ documentation
           
          
          for
          
           
            Implementation defined behavior control
           
          
          | 
外部链接
| 1. | Visual Studio 中的 C++ 杂注 | 
| 2. | GCC 接受的 杂注 | 
| 3. | IBM AIX XL C 16.1 中的 单个杂注说明 与 标准杂注 | 
| 4. | Sun Studio 11 C++ 用户指南中的 附录 B. 杂注 | 
| 5. | Intel C++ 编译器杂注 | 
| 6. | HP aCC 编译器杂注 |