这段代码编译可以通过,但是链接通过不了
报错:
错误 2 error LNK2019: 无法解析的外部符号 _add,该符号在函数 _main 中被引用
#include <stdio.h> #include <Windows.h> int add(int a, int b); int main() { add(1, 2); system("pause"); return 0; }这段代码可以通过编译阶段,但是无法通过链接阶段
报错:
错误 2 error LNK2019: 无法解析的外部符号 _add,该符号在函数 _main 中被引用
由上述两个相同功能但数据类型不同的add函数的报错可以看出:add函数在编译之后存在符号表中的名字都是_add,而main函数名字是_main
所以,
VS编译器编译C文件时对于相同名字的函数并不做区分
,都是以
_函数名
来命名
这段代码可以通过编译,但是不能通过链接
报错:
error LNK2019: 无法解析的外部符号 “int __cdecl add(int,int)” (?add@@YAHHH@Z),该符号在函数 _main 中被引用
error LNK2019: 无法解析的外部符号 “double __cdecl add(double,double)” (?add@@YANNN@Z),该符号在函数 _main 中被引用
由报错可以看出:自定义函数的函数名经过编译之后,变成了另外一种表现形式,对于同名函数有区分度
命名规则:【?函数名@@YA返回值数据类型对应字母+形参数据类型对应字母@Z】
对应关系:
int -> Hdouble-> Nfloat -> Mchar -> Dvoid -> Xbool -> _N例如:
int add(int ,int ) -> ?add@@YAHHH@Z
double func(double,double) -> ?func@@YANNN@Z
由此可以看出gcc编译c之后,自定义函数的函数名不变,对于同名函数没有区分度。
由此可以看出g++编译CPP文件之后,自定义函数的函数名改变了,可以对同名函数进行区分。
命名规则:【_Z + 函数名字长度 + 函数名 + 形参数据类型首字母】
例如:
int add(int ,int ) -> _Z 3 add i i
int func(double ,double ,double) -> _Z 4 func d d d
总结:无论是Windows操作系统还是Linux操作系统,基于这些操作系统的主流编译器都有一下特点:
编译C文件: 编译之后,对于 相同函数名的自定义函数 无区分度编译CPP文件:编译之后,对于 相同函数名的自定义函数 有区分度结:无论是Windows操作系统还是Linux操作系统,基于这些操作系统的主流编译器都有一下特点:
编译C文件: 编译之后,对于 相同函数名的自定义函数 无区分度编译CPP文件:编译之后,对于 相同函数名的自定义函数 有区分度因此,至于是 命名规则 导致 C语言不支持函数重载而CPP支持函数重载 ,还是 C语言不支持函数重载而CPP支持函数重载 导致 命名规则如此,其因果关系就仁者见仁智者见智啦