【问题标题】:In C and C++, why is each .h file usually surrounded with #ifndef #define #endif directives?在 C 和 C++ 中,为什么每个 .h 文件通常都被 #ifndef #define #endif 指令包围?
【发布时间】:2011-01-03 13:31:12
【问题描述】:

为什么每个 .h 文件都以 #ifndef #define #endif 开头?我们当然可以在没有这些指令的情况下编译程序。

【问题讨论】:

  • 谷歌“包括警卫”

标签: c++ c c-preprocessor include-guards


【解决方案1】:

这是一个所谓的“包含守卫”。目的是为了防止文件被多次包含时必须被多次解析。

【讨论】:

  • 并防止同一类的多个定义。
  • 有没有 #import 指令,或者这只是我的想象?
  • @Autopulated:这就是他多次解析的意思。除了类重新定义之外,还有更多的事情需要担心;都被“多重解析”封装了。
  • @janneb @GMan:我知道所有这些事情,但我不知道它到底是什么。我知道类、变量等的重新定义,但这很不舒服,但并不危险。你能给我一些危险行为的例子吗?
  • @Tom:您可能还记得 Visual C++,它是针对 COM 类型库的供应商特定扩展。或者来自 Objective-C/C++。
【解决方案2】:

它可以防止单个文件的多个包含。同样可以使用

#pragma once

指令,但那些 #ifndef 是标准的,因此每个编译器都支持。

【讨论】:

  • #pragma 一次。是特定于编译器的扩展。
  • ...但公平地说,这是一个广泛支持的版本
【解决方案3】:

它被称为包含保护。您可以不使用它们进行编写,直到您开始编写大型程序并发现需要从 .c 文件中直接或间接地多次包含同一个 .h 文件。然后,如果没有包含保护,您将得到多个定义错误,但使用它们,头文件内容仅解析一次并跳过所有后续时间,避免这些错误。始终使用它们是一个好习惯。

【讨论】:

    【解决方案4】:

    如果我理解正确,您想知道在没有包含保护的情况下,是否多次包含头文件会导致错误或危险行为。这是在排除多个定义等之后。

    想象一个恶意程序员,其头文件没有包含保护。他的头文件定义了一个宏,SZ,这是您用于静态分配数组的大小。程序员可以这样写他的头文件:

    #ifndef SZ
    #define SZ 1024
    #else
    #if SZ == 1024
    #undef SZ
    #define SZ 128
    #else
    #error "You can include me no more than two times!"
    #endif
    #endif
    

    现在,如果你包含一次头文件,你得到SZ等于1024。如果你包含两次,SZ变成128。当然,大多数现实世界的程序员都没有恶意,也没有人真正像上面那样写代码。

    请注意,C 标准允许assert.h 多次成为#included,其行为取决于在包含assert.h 时是否定义了NDEBUG。所以,assert.h 不能包含守卫。不过,这是一项功能,而不是错误。

    【讨论】:

      【解决方案5】:

      如果头文件包含类似的定义

      int i;
      在没有保护的情况下被多次包含,将产生编译错误。
      ifndef 检查是否未定义某些预处理器变量(第一次未定义),然后明确定义它以避免再次被捕获。 在 MSVC 中,您还可以使用
      #pragma once
      代替 ifndef's。

      【讨论】:

        猜你喜欢
        • 2010-12-11
        • 1970-01-01
        • 1970-01-01
        • 2014-12-08
        • 2011-03-15
        • 1970-01-01
        • 1970-01-01
        • 2023-03-19
        • 1970-01-01
        相关资源
        最近更新 更多