每个可重定位目标模块m都有一个符号表(.symtab),它包含m所定义和引用的符号的信息,不包含局部变量的信息。链接器的上下文(context)中有三种不同的符号(变量和函数):
1、由m定义并能被其他模块引用的全局符号。
2、由其他模块定义并被m引用的全局符号。
3、只被m模块定义和引用的本地符号,如被static修饰的函数或者全局变量。
上面说了被static修饰的全局变量,它仅在自己的模块中可被使用。以下比较被static修饰的全局变量和局部变量。
对全局变量而言,被static修饰,意味着“对此文件专用”。可以利用这个属性(相当于java中的private)来更好的封装,进行私有化。联想到ospf模块中很多.c文件中的小函数都是static的,只可以被本文件中的其他函数调用,而不可以被其他文件中的函数调用。
而对局部变量而言,它本来是在程序运行时临时从栈中分配空间的,但是被static修饰之后,就是“从静态内存”分配的变量了。此时,它虽然是局部变量,但是并不在模块退出后消失。举例如下:
int f()
{
static int x = 0;
return x;
}
int g()
{
static x = 1;
return x;
}
此时,编译器在.bss中为这两个x分配空间,并export两个唯一的本地链接器符号给汇编器。比如,可以用x.1表示函数f中的定义,而用x.2表示函数g中的定义。