编译器编译程序的过程+函数重载原理(为什么c++可以函数重载而c语言不行)

**编译器编译程序的过程**

假定程序员写出的3个文件:

func.h(函数声明)

func.c(定义函数)

test.c(main函数中使用函数)

1.预处理 -> 头文件展开、宏替换、条件编译、去掉注释

生成 func.i     test.i

2.编译 -> 检查语法,生成汇编代码(仍然是给人看的一种语言)

生成 func.s     test.s

3.汇编 -> 汇编代码转换为二进制机器代码

生成 func.o     test.o

4.链接 -> 将.o文件链接在一起使用

生成a.out

编译时,如果遇到函数,就会在符号表(就是一块空间)里面先命名一个符号来存放函数的地址,.i文件是分开编译的,如果有多个.i文件会出现以下情况:

如果函数的使用在定义之前编译,无法在符号表里找到对应函数地址,则就先记为"?"(暂时未知),在全部编译结束后的链接过程"?"在符号表里找到并替代为相应的函数地址,如果函数的定义在使用之前编译,则可以直接在符号表里面找到对应函数地址直接使用。

函数重载问题:

上面可以知道函数的使用是需要先在符号表里面命名一个特殊符号来存放函数的地址

C语言不支持函数重载,c语言的符号表中是以函数名为符号来储存函数地址,函数名相同的重载函数的地址应该不同,于是符号表中存在两个同符号的函数地址,在查找使用时会存在歧义和冲突

C++的符号表中的符号不是以函数名命名的,不同编译器储存方式不同,称为函数名修饰规则

    g++的函数名修饰规则: _Z + 函数名长度 + 函数名 + 参数类型首字母

  (例如:  f(12) -> _Z1fi;    func(int a,int *p) -> _Z4funciPi)

有了函数名修饰规则,c++中重载函数所对应符号表中的符号就不同,查找时不存在歧义和冲突

链接的时候,text.o中的"?"就使用相同的函数名修饰规则在符号表里面查找符号,查找到相同的符号就拿出相应的函数地址来代替

(注:链接是在.o文件的基础上进行,所以链接时使用的符号表是.o文件当中的,为了方便演示,上面的符号都是.s中程序员能看懂的符号名,汇编后的符号名就只有机器能看懂了)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值