为什么我的包含防护不能阻止递归包含和多个符号定义?

时间:2013-02-16 11:55:20

标签: c++ header-files c++-faq include-guards

关于include guards的两个常见问题:

  1. 第一个问题:

    为什么不包含保护我的头文件的守卫相互的,递归的包含?我不断收到有关非现有符号的错误,这些符号显然存在,甚至在每次写下类似内容时都会出现更奇怪的语法错误:

    “A.H”

    #ifndef A_H
    #define A_H
    
    #include "b.h"
    
    ...
    
    #endif // A_H
    

    “b.h”

    #ifndef B_H
    #define B_H
    
    #include "a.h"
    
    ...
    
    #endif // B_H
    

    “的main.cpp”

    #include "a.h"
    int main()
    {
        ...
    }
    

    为什么我会收到编译“main.cpp”的错误?我需要做些什么来解决我的问题?


    1. 第二个问题:

      为什么不包含防止多个定义的警卫?例如,当我的项目包含两个包含相同标题的文件时,链接器有时会抱怨多次定义某个符号。例如:

      “header.h”

      #ifndef HEADER_H
      #define HEADER_H
      
      int f()
      {
          return 0;
      }
      
      #endif // HEADER_H
      

      “source1.cpp”

      #include "header.h"
      ...
      

      “source2.cpp”

      #include "header.h"
      ...
      

      为什么会这样?我需要做些什么来解决我的问题?

2 个答案:

答案 0 :(得分:0)

fiorentinoing的答案在Git 2.24(2019年第四季度)中得到了回应,在Git代码库中也进行了类似的代码清除。

请参见commit 2fe4439René Scharfe (rscharfe)(2019年10月3日)。
(由Junio C Hamano -- gitster --commit a4c5d9f中合并,2019年10月11日)

  

树范围:删除重复的#include指令

     

发现于:

git grep '^#include ' '*.c' | sort | uniq -d

答案 1 :(得分:-1)

首先,您应该100%确保在“ include guards”中没有重复项。

使用此命令

grep -rh "#ifndef" * 2>&1 | uniq -c | sort -rn | awk '{print $1 " " $3}' | grep -v "^1\ "

您将1)突出显示所有包含防护,针对每个包含名称获得带有计数器的唯一行,对结果进行排序,仅打印计数器和包含名称,然后删除真正唯一的计数器。

提示:这等效于获取重复的包含名称列表