Ifdef Cplusplus

Jul 16, 2017


#ifdef __cplusplus 使用的目的

由于C++和C编译器有一定的不同,因此在C++与C语言混合调用的情况下,需要通过一种声明的方式来告知编译器使用哪种方式来进行编译。

C++支持重载而C不支持,因此函数在编译过程中在符号库中的名称两者不同。例如,假设某个函数的原型为:voidfoo( int x, int y );该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。例如,在C++中,函数void foo( int x, int y )与void foo( int x, float y )编译生成的符号是不相同的,后者为_foo_int_float。

#ifdef __cplusplus 常用格式

#ifdef __cplusplus
extern "C"{
endif
//some code
#ifdef __cplusplus
}
endif

首先,__cplusplus是C++里自定义的宏,上述代码的含义是:如果这是一段cpp代码,那么加入extern “C” {}来处理其中的代码。

加入extern “C” {}与否有什么区别呢?
看两个编译的实例就比较好理解了:
对于同一段代码:

int f(void){
	return 1;
}

在加入extern “C” {}的时候产生的汇编代码为:

file "test.cxx" 
.text 
.align 2 
.globl _f 
.def _f; .scl 2; .type 32; .endef 
_f: 
pushl %ebp 
movl %esp, %ebp 
movl $1, %eax 
popl %ebp 
ret

在不加时产生的汇编代码为:

.file "test.cxx" 
.text 
.align 2 
.globl __Z1fv 
.def __Z1fv; .scl 2; .type 32; .endef 
__Z1fv: 
pushl %ebp 
movl %esp, %ebp 
movl $1, %eax 
popl %ebp 
ret

产生的函数名,一个叫_f, 一个叫_Z1fv。 因此为了C++能够尽可能地对C兼容,并且能够使用C写好地库,必要时候需要加上extern “C” {}来加以声明。


上一篇博客:babun, windows上的shell
下一篇博客:cppcheck中文手册