flo*_*bue 1 c gcc include-guards c-preprocessor
Why does gcc ignore these header guards in this simple test program?
The header file is:
#ifndef MYHEADER_H
#define MYHEADER_H
#warning "header declared"
int some_int=0;
#endif
Run Code Online (Sandbox Code Playgroud)
And the two .c files are: main.c:
#include "header.h"
int main ()
{
return some_int;
}
Run Code Online (Sandbox Code Playgroud)
source.c:
#include "header.h"
int get_int()
{
return some_int;
}
Run Code Online (Sandbox Code Playgroud)
When compiling with:
gcc -o out main.c source.c
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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 version 9.2.1 20200130 (Arch Linux 9.2.1+20200130-2)
Run Code Online (Sandbox Code Playgroud)
Header guards guard against multiple inclusion in a single translation unit (usually a .c file and everything it includes, directly or indirectly).
您有两个翻译单元,main.c和source.c,它们是独立编译的(即使您使用单个命令行gcc main.c source.c)。这就是为什么您从链接器而不是编译器收到错误消息的原因。
如果你想定义一个对象,你应该在一个.c文件中进行,并extern在相应的.h文件中声明它。.c定义对象的文件只编译一次,其他多个.c文件都可以看到文件中的声明.h。