20171107-程序员的自我修养

今天看 C++在编译链接过程中的相关问题。


C++由于类的特殊性,一些内容必须由编译器和链接器共同支持才能完成工作(重复代码消除,构造函数,析构函数)。而且C++中的一些特性如虚函数、重载、继承等,背后的数据结构非常复杂,还会导致不同编译器和链接器之间相互不能通用。

首先看了4.4.1,重复代码消除

C++的某些特性会出现:在多个编译单元内多次被实例化的情况,如果简单的将重复的代码都保存下来,那么主要有以下几个问题:

1. 空间浪费

2. 地址较易出错(?)

3. 执行效率低,主要指cpu的指令cache命中率降低

GCC和Visual C++都对此进行了优化,方式类似,都采用单次链接的方式,重复的代码段将会被丢弃。


全局构造和析构

C++的构造函数在main之前执行,main之后会执行析构函数。

在main之前执行的,还有堆分配初始化(malloc、free),线程子系统等。

C++的ELF文件中,还有两个特殊的段:

.init:main函数之前执行的代码段

.fini:main正常退出之后执行的代码段

若用户将自定义的函数放在.init或.fini段内,则会在对应时间执行对应的代码段。


C++与ABI

不同编译平台的目标文件若可以相互链接,则必须满足下面的条件:

1. 采用相同的目标文件格式

2. 拥有同样的符号修饰标准

3. 变量的内存分布方式相同

4. 函数的调用方式相同

5. ……

上面五点这些和可执行代码二进制兼容性相关的内容成为ABI(Application Binary Interface)

ABI和API的区别

其实两者都是应用程序接口,但是层面不同,API为源代码层面的,ABI为二进制层面的。



ABI其实是C++兼容性不好的一大原因,如今又Visual C++和GCC两大派别,互相之间不兼容。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值