在C中包含保护惯例

cju*_*b39 9 c include-guards

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

#ifndef _EXAMPLE_H_
#define _EXAMPLE_H_
#include "example.h"
#endif
Run Code Online (Sandbox Code Playgroud)

强调约定是否重要?当我用Google搜索时,我看到了相互矛盾的信息.是否_EXAMPLE_H_甚至有相匹配的头的名称?

P.P*_*.P. 16

Does underscore convention matter?
Run Code Online (Sandbox Code Playgroud)

是.这很重要.

带有前导下划线的标识符后跟大写字母保留用于实现.所以你所拥有的将导致未定义的行为.

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

7.1.3保留标识符

每个标头声明或定义其关联子条款中列出的所有标识符,并可选地声明或定义其关联的未来库方向子条款和标识符中列出的标识符,这些标识符始终保留用于任何用途或用作文件范围标识符.

- 所有以下划线开头的标识符以及大写字母或另一个下划线始终保留用于任何用途.

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

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

没有保留其他标识符.如果程序在保留它的上下文中声明或定义标识符(除了7.1.4允许的标识符),或者将保留标识符定义为宏名称,则行为是未定义的.

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

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

  • 一个常见的约定是将头名称映射为大写,并将`.h`替换为`_H`,因此`foobar.h`的守护将是`FOOBAR_H`.如果名称以'e'开头,例如'"elvis.h"`,则保护宏将是`ELVIS_H` - 并且以`E`开头的宏和一个数字或大写字母保留供`< errno.h中>`.实现将"ELVIS_H"定义为错误代码的可能性很小,但是你可以通过使用像`H_HEADER_NAME`而不是`HEADER_NAME_H`这样的约定来避免这种可能性. (3认同)