为什么在C++头文件中使用#ifndef和#define?

Asa*_*han 458 c c++ c-preprocessor

我一直在头文件的开头看到这样的代码:

#ifndef HEADERFILE_H
#define HEADERFILE_H
Run Code Online (Sandbox Code Playgroud)

并在文件的最后是

#endif
Run Code Online (Sandbox Code Playgroud)

这样做的目的是什么?

Lir*_*una 494

这些被称为#include警卫.

包含标头后,它会检查是否定义了唯一值(在本例中HEADERFILE_H).然后,如果未定义,则定义它并继续到页面的其余部分.

当再次包含代码时,第一个ifndef失败,导致空白文件.

这可以防止双重声明任何标识符,例如类型,枚举和静态变量.

  • 它还可以防止递归包含......想象一下,"alice.h"包含"bob.h","bob.h"包含"alice.h",它们没有包含警戒...... (91认同)
  • @ЈЈу:`#pragma once`不可携带; 推荐使用常见的`#ifndef`成语. (6认同)
  • Koning Baard XIV:VC 甚至有一个`#pragma once`,它的作用相同:-) (2认同)
  • @CIsForCookies将“一个定义规则”打入您喜欢的搜索引擎。 (2认同)
  • 打开一个文件、丢弃其所有内容并一遍又一遍地关闭它的成本听起来可能并不多,但对于由数百个其他标头(例如“windows.h”)传递的大型标头来说,提供的低级内容简单的类型定义,如“stdint.h”、“types.h”等),每个源文件只打开一次和打开一百次(其中只有第一次才有效)之间的区别,尤其是在并行构建(即使添加的少量争用也会对旋转磁盘存储造成很大损害),在大型构建中累积起来。 (2认同)

Roy*_*Roy 32

#ifndef <token>
/* code */
#else
/* code to include if the token is defined */
#endif
Run Code Online (Sandbox Code Playgroud)

#ifndef检查给定标记是#defined在文件中还是在包含文件中更早; 如果没有,它包括它和关闭之间的代码#else,或者如果没有#else存在,#endif语句.#ifndef通常用于通过在包含文件后定义令牌并检查令牌未设置在该文件的顶部来使头文件具有幂等性.

#ifndef _INCL_GUARD
#define _INCL_GUARD
#endif
Run Code Online (Sandbox Code Playgroud)

  • 我知道这是一个旧的注释,但实际上下划线限制仅适用于"外部标识符" - 可能最终出现在编译对象的符号表中的标识符,即全局变量和函数名称.它不适用于宏名称. (5认同)
  • 保留以下划线开头的标识符; 你不应该自己定义它们.使用类似`#ifndef H_HEADER_NAME`的内容. (4认同)

小智 8

这可以防止多次包含相同的头文件.

#ifndef __COMMON_H__
#define __COMMON_H__
//header file content
#endif
Run Code Online (Sandbox Code Playgroud)

假设您已将此头文件包含在多个文件中.因此,第一次没有定义__COMMON_H__时,它将被定义并包含头文件.

下次定义__COMMON_H__时,它将不再包含.


小智 8

它们被称为 ifdef 或包含守卫。

如果编写一个小程序,似乎不需要它,但随着项目的增长,您可能会有意或无意地多次包含一个文件,这可能会导致编译警告,例如变量已声明。

  • #ifndef检查是否HEADERFILE_H未声明。

  • #define将声明HEADERFILE_H一次#ifndef生成 true。

  • #endif#ifndef就是要知道ie结尾的范围#ifndef

如果没有声明,即生成true,则仅执行和#ifndef之间的部分,否则不执行。这将防止再次声明标识符、枚举、结构等......#ifndef#endif