extern "C"

  有一种说法是C++是另一种C语言,虽然在C++创建之初的初衷也是期望一个更好的C,但是C++中全局变量和函数所采用的编译和连接方式却与C语言不完全相同。这就会引起C++和C语言在处理全局变量和函数时所采用的不同方式,并且当这两种方式需要C++与C兼容时,就会引入一些平衡两种处理方式的另一种处理方法。

      下面的代码段,在C程序里,应该经常可见

  1. #ifdef __cplusplus   
  2. extern "C" {  
  3. #endif   
  4. 。。。。。。  
  5. #ifdef __cplusplus   
  6. }  
  7. #endif  
#ifdef __cplusplus
extern "C" {
#endif
。。。。。。
#ifdef __cplusplus
}
#endif
这是什么意思呢?

其实简单点说,在extern "C" 中修饰的变量和函数是按照C语言编译和连接的,下面会简单的说明不同编译方式对函数符号的影响。


一,extern "C"是什么意思

      我们知道extern是C/C++语言中表明某个函数或者变量作用范围的关键字,就是一个变量在一个文件中被定义成全局变量,可以用这个关键字来在其它文件中引用,这个关键字是告诉编译器其所声明的符号(函数或变量)可以在这个模块中使用。这里要区分的是

  1. int var_c;  
int var_c;
表示变量的定义,而

  1. extern int var_c;  
extern int var_c;
       不是变量的定义,而是一个声明,也就是说,并不会为变量var_c 分配内存空间,extern可以被多次使用同一个变量,但var_c的变量定义只能是被定义一次,如果多次定义,就会出现连接错误。
  

        所以,extern "C" 表示 意思如下:

  1. 被修饰的符号(函数或变量)是extern类型的,这是C和C++都支持的关键字,并且都有表示模块之间变量引用的功能。
  2. "C"表示按C的方式编译和连接,为什么需要这样的处理,前面也说了,是为了在C++中对C处理全局变量和函数的方式兼容,那为什么需要兼容呢,他们不是一样的吗?当然有很多的地方还是不一样的,比如C++支持函数重载等等呢,是吧。

        在C语言中经常出现的另一个修改函数关键字的作用是static,被这个关键字修饰的变量和函数就是只能在本模块中使用,这就是说如果两个模块中,需要出现同名函数,那么用static是可以实现的,这样会对另一个模块“隐藏”这个函数的定义。

二,对编译的影响

      现在我们关心的是:在C++中,没有extern "C" 修饰和有extern "C" 修饰的符号有什么不同呢?
      假设函数原型如下
  1. int function(char *original);  
int function(char *original);

这定义对C和C++都是一样的。

在被C++编译之后,我的编译器输出的符号为
  1. client:00000000004006a8 R _IO_stdin_used  
  2. client:                 w _Jv_RegisterClasses  
  3. client:0000000000400578 T _Z8functionPc  
  4. client:00000000006007b8 d __CTOR_END__  
  5. client:00000000006007b0 d __CTOR_LIST__  
client:00000000004006a8 R _IO_stdin_used
client:                 w _Jv_RegisterClasses
client:0000000000400578 T _Z8functionPc
client:00000000006007b8 d __CTOR_END__
client:00000000006007b0 d __CTOR_LIST__
可以看出function在编译器中的符号库中表示为_Z8functionPc,这会根据编译器的不同,而有所不同。

在被C编译之后,输出为:
  1. client:00000000006008b8 b dtor_idx.6147  
  2. client:0000000000400470 t frame_dummy  
  3. client:00000000004004cd T function  
  4. client:0000000000400498 T main  
client:00000000006008b8 b dtor_idx.6147
client:0000000000400470 t frame_dummy
client:00000000004004cd T function
client:0000000000400498 T main
发现了吧,C++ 和C编译器对同一个函数编译之后的符号是不一样的,C就是以函数名作为符号,而C++比较复杂,这也是为什么C++可以支持重载,而C不能支持的原因了。

现在我以C的方式编译,但是加上extern "C" 关键字,其编译之后的结果和C编译方式的结果是一样的。这里就不给出结果了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值