系统层知识

弱符号和强符号

2018-02-07  本文已影响332人  wilkingwang

     链接过程实质上就是把不同目标文件粘在一起,对不同目标文件中定义或引用的相同名字进行决议resolve和绑定binding。

一、符号的分类

     1、定义在本目标文件中的全局符号,可以被其它文件引用。

     2、在本目标文件中引用的全局符号,却没有定义在本目标文件,这一般叫做外部符号(External Symbol), 也就是我们前所谓符号引用。

     3、段名,这种符号通常由编译器产生,它的值就是该段的起始地址。

     4、局部符号,这类符号只在当前编译单元内部可见。局部符号对于链接过程没有作用,链接器往往忽略它们。    

     5、行号信息,即目标指令与源代码中代码行的对应关系,它是可选的。

     链接关心的是各种全局符号。

二、弱符号与强符号

在C语言中,函数和初始化的全局变量(包括显式初始化为0)时强符号;未初始化的全局变量时弱符号。

注意:强符号和弱符号是针对定义来说的,不是针对引用来说的。

图1 强符号和弱符号

例如:weak_num、weak_num2是弱符号;strong_num和fun事强符号;ext即非强符号也非弱符号,因为他是一个外部变量的引用。

1、强符号

在链接时经常会碰到重复定义。多个目标文件中含有名字相同全局符号的定义,那么这些目标文件在链接的时候将会出现符号重复定义的错误。此类符号被称之为强符号: 对C语言来说,编译器默认函数和初始化了的全局变量为强符号。

不同的目标文件中不能有同名的强符号,否则不能链接在一起。

2、弱符号

        未初始化的全局变量为弱符号。

        也可以通过GCC的 __attribute ((weak)) 来定义一个强符号为弱符号。

声明一个符号fun,属性为weak,但并不定义它,这样链接器将此为定义的weak symbol赋值为0。调用未符号的弱符号会core dump。

3、查看一个目标文件中符号类型

nm ***.o

4、强符号、弱符号使用规则

1)同名的强符号只能有一个,否则编译器会报重复定义。

2)允许一个强符号和多个弱符号,但定义会选择强符号

3)当有多个弱符号时,编译器会选择占用空间最大的那个。

上一篇下一篇

猜你喜欢

热点阅读