代码之家  ›  专栏  ›  技术社区  ›  Benedikt S. Vogler

为什么include需要进一步的依赖关系?

  •  0
  • Benedikt S. Vogler  · 技术社区  · 7 年前

    我现在的理解是这样的。如果我错了,请纠正我。当我将C++库(例如,开源项目)包含到我的项目中时,我必须包含.h文件,以便编译器知道所包含的库的接口。然后,所包含库的编译代码由链接器链接。

    但现在在编译期间,包含的头文件需要另一个依赖项。如果我要包含这个依赖项的头文件,在包含每个依赖项之前,这不会变成一个递归循环吗?为什么需要?这不应该是链接器关心的问题吗?编译的库包含依赖项。

    我在使用Xcode 9.4的时候偶然发现了这个项目。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Bilal Siddiqui    7 年前

    编译器把代码翻译成机器语言。然后,使用链接器将所述代码与其他机器代码串在一起。谷歌更多的关于我写的东西,如果困惑的话;这是一个简化,缺少更精细的细节。

    当你打字的时候 #include <cstdint> 例如,一个 ,这是另一个单独的程序,如果您愿意,可以在 #包括<cstdint> 并将该行替换为 cstdint.hh

    通常,这些 #include <...> 其他 #include . 然而,这并不是一个保证。

        2
  •  0
  •   MSalters    7 年前

    你识别的风险存在。不过,这不是自动的。如果 a.h 包括 b.h c.h ,嵌套包含没有问题。

    如果 b、 小时 c、 小时 ,和 还包括 c、 小时 间接地。这里的风险并不是递归,而是对 c、 小时

    通常的解决方案是每个报头都以

    #ifndef A_H_INCLUDED
    #define A_H_INCLUDED
    
    // actual contents of "a.h"
    

    #endif // A_H_INCLUDED
    

    现在,第二个 c、 小时 是无害的。当这种情况发生时, C_H_INCLUDED c、 小时 第二次,节省了几毫秒的磁盘I/O。

    链接器无法解决此问题,因为双重定义问题发生在涉及链接器之前。它发生在单个翻译单元的层次上。一个翻译单元基本上是一个.cpp文件,在它的所有.h文件都包含在内之后。每个TU都由编译器单独处理,这个编译器会遍历双定义。链接器不太关心复制。重复的函数定义是链接器的问题,类定义不是。

    推荐文章