简体   繁体   English

c 标题保护被忽略?

[英]c header-guards are ignored?

Why does gcc ignore these header guards in this simple test program?为什么 gcc 在这个简单的测试程序中忽略了这些头文件保护?

The header file is:头文件是:

#ifndef MYHEADER_H
#define MYHEADER_H

#warning "header declared"

int some_int=0;

#endif

And the two .c files are: main.c:这两个 .c 文件是: main.c:

#include "header.h"

int main ()
{
    return some_int;
}

source.c:来源.c:

#include "header.h"

int get_int()
{
    return some_int;
}

When compiling with:编译时:

  gcc -o out main.c source.c

I get the following output:我得到以下输出:

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

As expected, the warning shows up, when the compiler includes the header file for the first time.正如预期的那样,当编译器第一次包含头文件时,会出现警告。 But why wont the header guards stop the second inclusion?但是为什么头球后​​卫不会阻止第二次包含?

The gcc version is: gcc 版本是:

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

Header guards guard against multiple inclusion in a single translation unit (usually a .c file and everything it includes, directly or indirectly).标题保护防止在单个翻译单元中多次包含(通常是.c文件及其直接或间接包含的所有内容)。

You have two translation units, main.c and source.c , and they're compiled independently (even if you use a single command line line gcc main.c source.c ).您有两个翻译单元main.csource.c ,它们是独立编译的(即使您使用单个命令行gcc main.c source.c )。 That's why you're getting an error message from the linker, not from the compiler.这就是为什么您从链接器而不是编译器收到错误消息的原因。

If you want to define an object, you should do it in a .c file and declare it as extern in the corresponding .h file.如果你想定义一个对象,你应该在一个.c文件中进行,并在相应的.h文件中将其声明为extern The .c file defining the object is compiled just once, and multiple other .c files can see the declaration in the .h file.定义对象的.c文件只编译一次,其他多个.c文件可以看到.h文件中的声明。

It's not ignoring them.这不是无视他们。 You have two separate compilation units there and each one needs header.h .你有两个独立的编译单元,每个都需要header.h Header guards are intended to prevent a single compilation unit from including the same header twice.标头保护旨在防止单个编译单元两次包含相同的标头。 For example.例如。 If main.c included header.h' directly, but also included foo.h which also included header.h , when all the includes are expanded the header guard ensures that header.h`'s contents only appear once.如果main.c header.h' directly, but also included包含header.h' directly, but also included foo.h which also included header.h , when all the includes are expanded the header guard ensures that header.h` 的内容只出现一次。

There are 2 compilation units : 1 for main.c and 1 for source.c .有 2 个编译单元:1 个用于main.c ,1 个用于source.c These are compiled separately (and completely independently) by the compiler, resulting in 2 object files (eg. main.o resp. source.o ).这些由编译器单独(并且完全独立)编译,从而产生 2 个目标文件(例如main.osource.o )。 Each of these prints the warning :每个都打印警告:

In file included from main.c:1:
header.h:4:2: warning: #warning "header declared" [-Wcpp]
    4 | #warning "header declared"
      |  ^~~~~~~

These object files are then linked into an executable out by the linker.这些对象文件,然后链接到可执行文件out链接器。

But the linker discovers that both object files define the same symbol some_int , and thus fails to generate the executable, resulting in :但是链接器发现两个目标文件都定义了相同的符号some_int ,因此无法生成可执行文件,导致:

/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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM