在C中包含保护惯例

时间:2013-06-25 21:06:46

标签: c include-guards

设置包含警卫的传统方法是什么?我通常把它们写成(例如h.h):

#ifndef _EXAMPLE_H_
#define _EXAMPLE_H_
#include "example.h"
#endif

下划线惯例是否重要?当我用Google搜索时,我看到了相互矛盾的信息。 _EXAMPLE_H_是否必须匹配标题的名称?

2 个答案:

答案 0 :(得分:16)

Does underscore convention matter?

是。这很重要。

带有前导下划线和大写字母的标识符保留用于实现。所以你拥有的东西会导致未定义的行为。

以下是C标准用于命名标识符(C11 draft)的规范:

7.1.3保留标识符

  

每个标头声明或定义其中列出的所有标识符   相关子条款,并可选择声明或定义标识符   列在其相关的未来图书馆方向子条款和   标识符,总是保留用于任何用途或用作   文件范围标识符。

     

- 所有以下划线开头的标识符和   大写字母或另一个下划线总是保留给任何人   使用

     

- 始终保留以下划线开头的所有标识符   用作普通和标记中具有文件范围的标识符   命名空格。

     

- 以下任何子条款中的每个宏名称(包括   未来的图书馆方向)保留供指定使用,如果有的话   包含其相关标头;除非另有明确说明   (见7.1.4)。 - 所有标识符都带有外部链接   以下子条款(包括未来的图书馆方向)和   errno始终保留用作外部标识符   linkage.184) - 每个标识符都有文件范围列出的任何一个   以下子条款(包括未来的图书馆方向)是   保留用作宏名称和文件范围的标识符   如果包含任何相关标题,则在同一名称空间中。

     

不保留其他标识符。如果程序声明或定义   保留它的上下文中的标识符(除了   由7.1.4)允许,或将保留标识符定义为宏名称,   行为未定义。

     

如果程序删除(使用#undef)任何宏的定义   上面列出的第一个组中的标识符,行为未定义。

在不违反上述任何规定的情况下,包含保护名称可以是任何内容,并且不必是头文件的名称。但通常我看到/使用的约定是使用与头文件名相同的名称,这样就不会引起任何不必要的混淆。

答案 1 :(得分:-1)

对于如何命名警卫没有绝对的要求。它不必与标题名称匹配。我见过(并使用过自己)一些使用UUID的东西,基本上由一个随机生成的十六进制字符串组成。

技术上,正如KingsIndian所说,以下划线开头的标识符是保留的:

  

规则,从ANSI Sec转述。 4.1.2.1,是:

1. All identifiers beginning with an underscore followed
   by an upper-case letter or another underscore are always
   reserved (all scopes, all namespaces).
2. All identifiers beginning with an underscore are reserved
   for ordinary identifiers (functions, variables, typedefs, enumeration
   constants) with file scope.
...
     

comp.lang.c FAQ list · Question 1.29

也许新的ISO C11(?)标准放宽了这些规则,但这已成为一段时间的底线。