- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
C中extern“C”含义深层探索
1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同。作为一种欲与C兼容的语言,C++保留了一部分过程式语言的特点(被世人称为“不彻底地面向对象”),因而它可以定义不属于任何类的全局变量和函数。但是,C++毕竟是一种面向对象的程序设计语言,为了支持函数的重载,C++对全局函数的处理方式与C有明显的不同。
2.从标准头文件说起某企业曾经给出如下的一道面试题:为什么标准头文件都有类似以下的结构??
#ifndef __INCvxWorksh#define __INCvxWorksh?#ifdef __cplusplusextern C {#endif?/*...*/?#ifdef __cplusplus}#endif?#endif /* __INCvxWorksh */
显然,头文件中的编译宏“#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif” 的作用是防止该头文件被重复引用。那么
#ifdef __cplusplusextern C {#endif?#ifdef __cplusplus}#endif
的作用又是什么呢?我们将在下文一一道来。
3.深层揭密extern C extern C 包含双重含义,从字面上即可得到:首先,被它修饰的目标是“extern”的;其次,被它修饰的目标是“C”的。让我们来详细解读这两重含义。 被extern C限定的函数或变量是extern类型的; extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。记住,下列语句:
extern int a;
仅仅是一个变量的声明,其并不是在定义变量a,并未为a分配内存空间。变量a在所有模块中作为一种全局变量只能被定义一次,否则会出现连接错误。 通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数。 与extern对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被extern “C”修饰。 被extern C修饰的变量和函数是按照C语言方式编译和连接的; 未加extern “C”声明时的编译方式 首先看看C++中对类似C的函数是怎样编译的。 作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:?
void foo( 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。
同样地,C++中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,我们以.来区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。 未加extern C声明时的连接方式 假设在C++中,模块A的头文件如下:
// 模块A头文件 moduleA.h#ifndef MODULE_A_H#define MODULE_A_Hint foo( int x, int y );#endif
在模块B中引用该函数:
// 模块B实现文件 moduleB.cpp#include moduleA.hfoo(2,3);
实际上,在连接阶段,连接器会从模块A生成的目标文件moduleA.obj中寻找_foo_int_int这样的符号! 加extern C声明后的编译和连接方式 加extern C声明
您可能关注的文档
最近下载
- 企业内控应用手册之信息系统风险控制矩阵.pdf VIP
- 复合场例题与习题(含答案).doc VIP
- 2024年昆明市官渡区国有资产投资经营有限公司人员招聘笔试备考题库及答案解析.docx VIP
- 2025年四川广安市广安区白市镇人民政府选用片区纪检监督员1人备考题库及答案解析.docx VIP
- 2025四川广安市广安区花桥镇人民政府选用片区纪检监督员1人考试备考题库及答案解析.docx VIP
- 汇川PN伺服Epos使用(FB_Servo_111)使用方法详解_带程序_V2.pdf VIP
- 地基GPS遥感大气可降水量:原理、方法与气象应用的深度剖析.docx VIP
- 云南昆明市官渡区国有资产投资经营有限公司招聘笔试题库2023.pdf VIP
- 某某某公司特变电工股份有限公司廉政手册.doc VIP
- 《城市热岛效应》.ppt VIP
文档评论(0)