定义像 __BASH_H__ 这样仅在设置之前使用的预处理器宏的目的是什么?

Ric*_*mas 12 c bash

我现在正在阅读一些开源代码,我在这个 C 头文件的顶部看到以下代码行:

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

我没有__BASH_H__在代码库的其他任何地方看到引用,所以我怀疑它是间接使用的(即由 shell、C 编译器或第三方库),而不是由代码本身使用。

我在谷歌上搜索了“ BASH_H ”,我看到它被其他开源库使用(即这里这里),所以我假设我的假设方向是正确的。

然而,Google 搜索结果不包含任何关于此声明、其目的、用途等的官方文档。我只看到总共 2 页的搜索结果,其中大部分看起来无关紧要。

我假设它在某种程度上与 相关bash,但我对缺乏官方文档感到困惑。有人能指出我正确的方向吗?

Ste*_*itt 30

它\xe2\x80\x99是一个经典的标头保护:它确保标头仅包含一次。想象一下你有一个文件,上面写着

\n
#include "bash.h"\n#include "bash.h"\n
Run Code Online (Sandbox Code Playgroud)\n

第一个#include将导致__BASH_H__被定义。这将导致#ifndef第二次包含失败,因此 \xe2\x80\x9cuseful\xe2\x80\x9d 内容将不会再次包含 \xe2\x80\x99。

\n

出于多种原因,避免双重声明是有用的;主要的一个是 C 中的许多元素不能被声明两次,特别是structs。

\n

(单个文件不太可能两次包含 a 标头,但当标头包含其他标头时,很容易发生多次包含:a.cincludesb.hc.h,以及b.hincludes c.h。)

\n

\xe2\x80\x99s 此类防护没有外部用途,它们是头文件的实现细节。

\n

选择的名称__BASH_H__有很好的机会是独一无二的;可以使用任何足够可区分的标记来代替,,,,idontwantbashhincludedtwice等等single_bash_h。它没有值,重要的是它是否被定义。它的唯一用途是在一对#ifndef/#define行中。(它\xe2\x80\x99 通常作为注释与匹配的 一起重复#endif,但这对预处理器来说并不重要。)

\n

实现相同结果的常见 C 编译器扩展是#pragma once.

\n

  • 我确实注意到`__BASH_H__`是一个[**保留标识符**](https://en.cppreference.com/w/c/language/identifier#Reserved_identifiers),并且只能由实现使用。用户定义的标识符,即使对于编译指示保护来说,也不应该以下划线开头(特别是在 C++ 中,也不应该包含双下划线)。 (2认同)