[读书笔记]程序员的自我修养(3)

本文介绍了目标文件中的.bss段和.data段的作用,解释了自定义段的方法,以及如何避免符号名称冲突。此外还讨论了C/C++语言中强弱符号的区别,并提供了链接器处理这些符号的规则。

第三章 目标文件里有什么

1. .bss段是为未初始化的全局变量和局部静态变量(global_init_varabal和static_var)预留位置。初始化的全局变量和局部静态变量(global_uninit_var和static_var2)放在.data段。总的来说,包含程序指令的代码段和程序数据的数据段及.bss段。
原因:
数据区是可读写的,指令区时只读的,防止指令被有意和无意篡改
在缓存系统中,指令区和数据区有利于提高程序的局部性,提高命中率
指令和数据区的共享,节省大量空间

static int x1=0; //放在.bss,为0被编译器优化认为为未初始化,不占磁盘空间
static int x2=1; //放在.data

2. 自定义段:__attribute__((section("name"))) 把相应的变量和函数放到"name"作为段名的段中

3. 防止符号名称冲突,C语言源代码文件中的所有全部变量和函数编译后在相应的符号前加下划线"_"
GCC通过参数"-fleading-underscore"和"-fno-leading=underscore"来打开和关闭是否在C语言符号前加下划线
C++符号修饰:参见GCC的名称修饰标准
GCC的基本C++名称修饰方法:所有的符号都以"_Z"开头,对于嵌套的名字(在名称空间或者在类里面的),后面紧跟着一个"N",然后是各个名称空间和类的名字,每个名字前是名字字符串的长度,再以"E"结尾。

4. 判断当前编译的是不是C++代码
#ifdef __cplusplus
extern "C" {
#endif

void *memset(void *, int, size_t);

#ifdef __cplusplus
}
#endif

5. 对于 C/C++语言来说,编译器默认函数和初始化了的全局变量为强符号,未初始化的全局变量为弱符号。GCC中__attribute__((weak))来定义任何一个强符号为弱符号。(针对符号定义而非引用)
针对强符号的概念,链接器就按如下规则处理与选择多次定义的全局符号:
不允许强符号被多次定义(即不同的目标文件中不能有同名的强符号);如果有多个强符号定义,则链接器报重复定义错误
在强符号和弱符号同时存在的一个符号选择强符号
某个在所有目标中都是弱符号,则选择占用空间最大的

弱引用指定__attribute__((weakref)),对未定义的弱引用,链接器默认为0,不会报错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值