首页 > 解决方案 > c header-guards被忽略了吗?

问题描述

为什么 gcc 在这个简单的测试程序中会忽略这些标头保护?

头文件是:

#ifndef MYHEADER_H
#define MYHEADER_H

#warning "header declared"

int some_int=0;

#endif

这两个 .c 文件是: main.c:

#include "header.h"

int main ()
{
    return some_int;
}

来源.c:

#include "header.h"

int get_int()
{
    return some_int;
}

编译时:

  gcc -o out main.c source.c

我得到以下输出:

In file included from main.c:1:
header.h:4:2: warning: #warning "header declared" [-Wcpp]
    4 | #warning "header declared"
      |  ^~~~~~~
In file included from source.c:1:
header.h:4:2: warning: #warning "header declared" [-Wcpp]
    4 | #warning "header declared"
      |  ^~~~~~~
/usr/bin/ld: /tmp/ccmAbN1J.o:(.bss+0x0): multiple definition of `some_int'; /tmp/ccEd5PwN.o:(.bss+0x0): first defined here
    collect2: error: ld returned 1 exit status

正如预期的那样,当编译器第一次包含头文件时,就会出现警告。但是为什么标题守卫不会停止第二次包含呢?

gcc 版本是:

gcc version 9.2.1 20200130 (Arch Linux 9.2.1+20200130-2)

标签: cgccc-preprocessorinclude-guards

解决方案


标头防护可防止在单个翻译单元中多次包含(通常是.c文件及其直接或间接包含的所有内容)。

您有两个翻译单元,main.cand source.c,它们是独立编译的(即使您使用单个命令行 line gcc main.c source.c)。这就是为什么您从链接器而不是编译器收到错误消息的原因。

如果你想定义一个对象,你应该在一个文件中进行,并在相应的文件中.c声明它。定义对象的文件只编译一次,其他多个文件可以看到文件中的声明。extern.h.c.c.h


推荐阅读