http://blog.csdn.net/fandelion/article/details/6258319
我们经常在编程中碰到一种情况叫符号重复定 义。多个目标文件中含有相同名字的全局变量的定义,那么这些目标文件链接的时候就会出现符号重复定义的错误。比如在目标文件 A 和目标文件 B 都定义了一个全局整形变量global,并且都初始化,那么当 A 和 B 链接时会报错:
multiple definition of ‘global‘
对于C/C++来说,编译器默认函数和初始化了的全局变量为强符号,未初始化的全局变量为弱符号。我们也可以通过GCC的"__attribute__((weak))"来定义任何一个强符号为弱符号。
1
2
3
4
5
6
7
8
9
10
11
12
|
#include <stdio.h> extern
int
ext; // 非强符号也非弱符号
int
weak; // 弱符号
int
strong = 1; // 强符号
__attribute__((weak)) int
weak2 = 2; // 弱符号
int
main()
{ getchar ();
return
0;
} |
规则1:不允许强符号被多次定义。
规则2:如果一个符号在某个目标文件中是强符号,在其他文件中都是弱符号,那么选择强符号。
规则3:如果一个符号在所有的目标文件中都是弱符号,那么选择其中占用空间最大的一个。
强引用 和 弱引用:
系统中的某些扩展功能模块可能时有时无,如果要求系统在两种情况下都能够正常的工作,那么就需要在功能模块不存在时,主程序对这些引用不能报错——这就是强引用 和 弱引用的概念。
如果模块A引用模块B的一个函数时,如果模块B的这个函数不存在,模块A不报错。
默认的模块中对所有对外部符号的引用在链接时都是强引用,该符号必须能够被正确的“决议”(或者说“绑定”),否则连接器就会报错,GCC中科院通过 __attribute__((weakref))关键字显示的对一个外部符号的引用定义为弱引用,这样,即使连接的时候该符号没有正确的找到定义,链接 器也不会报错,而只是将该符号的值置为0。但这样得到的可执行程序在执行时会报错,因为当调用弱引用时,弱符号的地址为0,属于非法访问。因此,在程序中 调用一个外部符号时,应该先判断其值是否为0,若不为0再调用。
1
2
3
4
5
6
7
8
9
|
__attribute__((weakref)) void
foo();
int
main()
{ if (foo)
{
foo();
}
} |