材料
1. a.cpp
extern "C"{
#include "b.h"
}
int main(){
int c = Foo(2, 4);
return 0;
}
2. b.h
#ifndef _B_H
#define _B_H
int Foo(int a, int b);
#endif
3. b.c
#include "b.h"
int Foo(int a, int b){
static int c = 1;
return (a > b) ? a : b;
}
记录
1. 测试a.cpp中不带extern "C"的情况
1.1 使用gcc编译b.c,成为b.s汇编文件
命令:gcc -S .\b.c
结果:可以看到这里是_Foo。
图1
1.2. 使用g++编译不带extern "C"的a.cpp,成为a.s汇编文件
命令:gcc -S .\a.cpp
结果:可以看到这里调用的是_Z3Fooii。但是b.c的Foo函数编译的结果和此处调用的函数不一样,所以在链接时会出错。
图2
1.3. 使用gcc编译、链接不带extern "C"的a.cpp和b.c
命令:gcc .\a.cpp .\b.c -lstdc++ 和 gcc .\a.cpp .\b.c
结果:
使用gcc编译的结果是找不到Foo函数。
图3
注意:
但使用g++是可以编译成功的。
图4
这是因为,**c文件同cpp文件一样,也是可以按照C++的标准进行编译的。**我们再来使用C++标准编译C文件。
命令:g++ -S .\b.c -nostartfiles
结果:对比图1、图2可以知道,c文件和cpp文件编译的函数头是同一个格式,因此调用时就不会出错。
图5
2. 测试a.cpp中带extern "C"的情况
2.1. 使用gcc编译带extern "C"的a.cpp,成为a.s汇编文件
命令:gcc -S .\a.cpp
结果:对比图2,可以看到不同。此时a.cpp中调用的是c中编译得到的_Foo。
图6
2.2. 使用gcc编译、链接带extern "C"的a.cpp和b.c
命令:gcc .\a.cpp .\b.c -lstdc++ 和 gcc .\a.cpp .\b.c
结果:编译、链接成功。
图7
结论
- cpp文件使用c文件时,gcc编译器编译时需要让cpp文件指定编译的c文件按照C的标准编译,否则会因为编译的结果不匹配而链接错误。而g++编译器默认c文件按照C++标准编译。