c - 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)
解决方案
标头防护可防止在单个翻译单元中多次包含(通常是.c
文件及其直接或间接包含的所有内容)。
您有两个翻译单元,main.c
and source.c
,它们是独立编译的(即使您使用单个命令行 line gcc main.c source.c
)。这就是为什么您从链接器而不是编译器收到错误消息的原因。
如果你想定义一个对象,你应该在一个文件中进行,并在相应的文件中.c
声明它。定义对象的文件只编译一次,其他多个文件可以看到文件中的声明。extern
.h
.c
.c
.h
推荐阅读
- node.js - 函数在 Promise 结束之前完成
- java - d3.js 试图导出数据字符串
- python - for循环中的重复迭代
- python - 如何使用 .boxplot 函数在 matplotlib 的 pyplot 中修复“X 必须有 2 个或更少的维度”错误?
- html - 数据表对齐标题和数据列
- java - 从另一个 Fragment 获取值,然后将 Items 添加到自定义 recyclerview
- wso2 - WSO2 企业集成商 + WSO2 消息代理
- javascript - 使用 GET 传递参数传递空对象
- groovy - 如何使用 groovy 在 testSuite TearDown 中捕获请求和响应
- git - 在递归 git repo 中断开子模块的链接并使它们独立于原始引用