项目中包含多个相同的头文件:C vs C++
Multiple includes of same header file in project: C vs C++
这里我有一个示例工程,有两个源文件和一个头文件,如下:
main.c:
#include<stdio.h>
#include "personal.h"
int main(){
i = 5;
printf("Value is %d\n",i);
return 0;
}
sub.c:
#include "personal.h"
// do nothing
最后 personal.h:
#pragma once
int i;
每个 .c 文件都包含 personal.h,这是“受保护的”。我用 gcc 编译,一切正常:
>gcc sub.c main.c -o out
>./out
Value is 5
但是对于 g++,会发生这种情况:
>g++ sub.c main.c -o out
/tmp/cctYwVnO.o:(.bss+0x0): multiple definition of `i'
/tmp/ccPElZ27.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
在文件链接方式、预处理器 activity 等方面,C++ 和 C 有什么根本不同吗?我对 clang 等其他编译器进行了同样的尝试,同样的事情发生了。我可能在这里遗漏了一些愚蠢的东西。
sub.c 将包含 personal.h 并将在全局范围内创建变量 i。同样,main.c 也将包含 personal.h 并在全局范围内创建变量 i。最终,当您 link 时,在全局范围内有两个 i 定义,因此出现错误。
在 C 中,
int i;
为暂定定义。由于包含,您在两个编译单元中有一个 i
的暂定定义。 C 标准允许在多个编译单元中有暂定定义,但不强制实现接受它。 Unix C 编译器的自定义行为是允许它,但 gcc 有一个选项(-fno-common
)来阻止它并在 link 时间生成错误(这样你就可以检查编译器的代码,因为我想想微软的一个,它不允许它或允许更好的代码的平台——我知道 none 但这是 GCC 文档给出的基本原理)。
IIRC,C++ 没有这样的津贴。
请注意,您可能需要声明而不是 header 中的定义。因此对于上面的 i
它应该是
extern int i;
在header和一个
int i;
在 一个 .c
文件中的全局范围内。
这里我有一个示例工程,有两个源文件和一个头文件,如下:
main.c:
#include<stdio.h>
#include "personal.h"
int main(){
i = 5;
printf("Value is %d\n",i);
return 0;
}
sub.c:
#include "personal.h"
// do nothing
最后 personal.h:
#pragma once
int i;
每个 .c 文件都包含 personal.h,这是“受保护的”。我用 gcc 编译,一切正常:
>gcc sub.c main.c -o out
>./out
Value is 5
但是对于 g++,会发生这种情况:
>g++ sub.c main.c -o out
/tmp/cctYwVnO.o:(.bss+0x0): multiple definition of `i'
/tmp/ccPElZ27.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
在文件链接方式、预处理器 activity 等方面,C++ 和 C 有什么根本不同吗?我对 clang 等其他编译器进行了同样的尝试,同样的事情发生了。我可能在这里遗漏了一些愚蠢的东西。
sub.c 将包含 personal.h 并将在全局范围内创建变量 i。同样,main.c 也将包含 personal.h 并在全局范围内创建变量 i。最终,当您 link 时,在全局范围内有两个 i 定义,因此出现错误。
在 C 中,
int i;
为暂定定义。由于包含,您在两个编译单元中有一个 i
的暂定定义。 C 标准允许在多个编译单元中有暂定定义,但不强制实现接受它。 Unix C 编译器的自定义行为是允许它,但 gcc 有一个选项(-fno-common
)来阻止它并在 link 时间生成错误(这样你就可以检查编译器的代码,因为我想想微软的一个,它不允许它或允许更好的代码的平台——我知道 none 但这是 GCC 文档给出的基本原理)。
IIRC,C++ 没有这样的津贴。
请注意,您可能需要声明而不是 header 中的定义。因此对于上面的 i
它应该是
extern int i;
在header和一个
int i;
在 一个 .c
文件中的全局范围内。