弱符号与强符号
多个目标文件中含有相同名字全局符号的定义,那么这些目标文件链接的时候将会出现符号重复定义的错误。
比如我们在目标文件A和目标文件B都定义了一个全局整形变量global,并将他们都初始化,那么链接器将A
和B进行链接时会报错。
这种符号的定义可以被成为强符号(Strong Symbol)。有些符号的定义可以被称为弱符号(Weak Symbol)。
对于C/C++语言来说,编译器默认函数和初始化了的全局变量为强符号,未初始化的全局变量为弱符号。
通过GCC的"__attribute__((weak))"可以定义任何一个强符号为弱符号。
强符号和弱符号都是针对定义来说的,不是针对符号的引用。
1 extern int ext;
2
3 int weak;
4 int strong = 1;
5 __attribute__((weak)) int weak2 = 2;
6
7 int main(void)
8 {
9 return 0;
10 }
上段程序中,"weak"和"weak2"是弱符号,"strong"和"main"都是强符号,而"ext"既非弱符号也非强符号,因为它是
一个外部变量的引用(强符号和弱符号都是针对定义而言的)。
这对强弱的概念,链接器就会按如下规则处理与选择被多次定义的全局符号:
(1)不允许强符号多次被定义(即不同的目标文件不能有相同的强符号);如果有多个强符号定义,则链接器报符号重复定义错误。
(2)如果一个符号在某个目标文件中是强符号,在其它文件中都是弱符号,那么选择强符号。
(3)如果一个符号在所有目标文件中都是弱符号,那么选择其中占用空间最大的一个。比如目标文件A定义全局变量global为int型,
占4个字节;目标文件B定义global为double型,占8个字节,那么目标文件A和B链接后,符号global占8个字节(尽可能不要使用多个
不同类型的弱符号,否则容易导致很难发现的程序错误)。