C++ 知识点 - 为什么C语言不支持函数重载,C++又是如何支持的

C语言为什么不支持函数重载

在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接

  • 预处理

    • 宏替换
    • 注释替换
    • 条件编译
    • 头文件展开
  • 编译

    • 检查语法 语义
    • 讲C代码转换为汇编代码
  • 汇编

    • 把汇编代码转换为二进制代码
    • 生成符号表
  • 链接

    • 合并段表
    • 符号表的合并和重定位(链接器看到a.o调用Add,但是没有Add的地址,就会到b.o的符号表中找Add的地址,然后链接到一起。)

示例

如果当前文件只有函数的声明, 那么编译器就会在链接的时候去其他文件对应生成的符号表去找函数的地址,如果找不见,报的错误是LNK ,就是link错误, 链接器没有找到(Linux下编译程序的时候,出现/usr/bin/ld: cannot find -lxxx的错误,主要的原因是找不到相应的动态库,库文件没有导入到ld检索目录中。)

C是通过函数名字去其他符号表中寻找地址的, 调用执行过程如图:

C语言不支持函数重载, 因为编译的时候, 两个重载函数, 函数名相同, 在func.o 中的符号表中表示歧义, 链接的时候也存在冲突, 所以不支持。

C++ 是如何支持函数重载的

C++支持函数重载的原理--名字修饰(Name Mangling)

采用C语言编译器编译后结果:

采用C++编译器编译后结果:

通过以上分析我们可以看出gcc的函数修饰后名字不变。而g++的函数修饰后变成【_Z+函数长度+函数名+类型首字母】。在linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参数类型信息添加到修改后的名字中。