【C++】一篇文章搞懂为什么CPP支持函数重载而C不支持?

    科技2022-07-11  109

    探讨为什么CPP支持函数重载而C不支持?

    Windows操作系统下VS编译C文件Windows操作系统下VS编译CPP文件Linux操作系统下gcc编译C文件Linux操作系统下g++编译CPP文件

    Windows操作系统下VS编译C文件

    #include <stdio.h> #include <Windows.h> double add(double a, double b); int main() { add(1.0, 2.0); system("pause"); return 0; }

    这段代码编译可以通过,但是链接通过不了

    报错:

    错误 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文件时对于相同名字的函数并不做区分

    ,都是以

    _函数名

    来命名

    Windows操作系统下VS编译CPP文件

    #include <iostream> using namespace std; int add(int a, int b); double add(double a, double b); int main() { add(1.0, 2.0); add(1, 2); system("pause"); return 0; }

    这段代码可以通过编译,但是不能通过链接

    报错:

    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

    Linux操作系统下gcc编译C文件

    由此可以看出gcc编译c之后,自定义函数的函数名不变,对于同名函数没有区分度。

    Linux操作系统下g++编译CPP文件

    由此可以看出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支持函数重载 导致 命名规则如此,其因果关系就仁者见仁智者见智啦

    Processed: 0.017, SQL: 8