C++ Primer 5th外部链接与函数重载混用实现及相关疑问
问题1:实现逻辑是否正确
你的实现逻辑是完全正确的,符合C/C混合编程规范和《C Primer》提到的重载规则,原因如下:
- 头文件通过
__cplusplus宏做了编译区分:C编译器编译calc.c时,只会拿到C版本double calc(double)的声明,不会识别C++特有的类、重载语法,不会出现编译错误。 extern "C"的修饰逻辑正确:C编译器处理头文件时,extern "C"刚好修饰后续的double calc(double)声明,指定该函数使用C链接(符号名不做C特有的名字粉碎),可以和gcc编译出的calc.o中的C函数符号匹配。另外两个带类参数的重载函数是默认的C链接,支持重载,符号会按C规则粉碎,和calc.cxx中的实现匹配。- 编译指令符合规范:用gcc编译C源文件,g编译链接C源文件和目标文件,符号解析逻辑完全匹配,运行正常是预期结果。
小补充:你这种
extern "C"单独占一行、下一行放C函数声明的写法是合法的,等价于直接写extern "C" double calc(double);,没有语法问题。
问题2:C++版本calc前extern关键字的作用
这里的extern是C的关键字,作用是指定函数的外部链接属性,和C编译器没有关系,仅作用于C编译阶段:
- 核心作用是告诉C++编译器:这两个重载函数的定义不在当前包含头文件的翻译单元中,链接阶段需要去其他目标文件(这里就是
calc.cxx编译出来的目标文件)查找对应的符号。 - 全局命名空间下的函数默认就是外部链接属性,所以你就算把这两个extern去掉,代码也能正常编译运行。这里加extern主要是两个原因:一是和C版本的extern声明写法统一,提升代码可读性,明确告知读者这几个函数都是定义在外部源文件的;二是符合头文件声明外部函数的通用编程习惯,避免后续如果修改代码(比如不小心在头文件里写了函数实现)出现非预期的编译错误。
内容的提问来源于stack exchange,提问作者Itachi Uchiwa
相关产品推荐
相关产品推荐

