static关键字
1. static关键字修饰局部变量
使用static关键字修饰的局部变量同全局变量一样,是静态分配的,在程序开始执行时分配和初始化一次,在程序结束时被释放,这种变量通常位于.rodata、.data或.bss段中。未初始化的静态局部变量或全局变量自然位于.bss段中,初始化的静态局部变量或全局变量位于.data段中,如果加上const关键字,它就位于.rodata段中。
#include <stdio.h>
int main(void)
{
static int a = 10;
return 0;
}
还是使用readelf命令读取出elf文件信息:
$ readelf -a test
43: 0000000000601018 4 OBJECT LOCAL DEFAULT 25 a.2046
变量分配地址为0x601018,和前面分析的一样,在Section Headers处找到该地址位于.data段中,.data段起始地址为0x601008,长度为0x14。再使用hexdump工具查看一下a变量地址处的内容:
$ hexdump -C test
00001000 d6 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 |..@.............|
00001010 00 00 00 00 00 00 00 00 0a 00 00 00 47 43 43 3a |............GCC:|
其中0x1018地址处数据为0x0a 0x00 0x00 0x00,正是我们给a初始化的值。
2. static关键字修饰全局变量和函数
使用static关键字修饰的全局变量和函数主要是限制其作用域,对于普通的全局变量和函数,作用域是整个项目,也就是说你可以在其它源文件中使用本源文件中定义的全局变量或函数,只需要在使用之前,使用extern关键字声明该变量或函数就行了。而使用static关键修饰的全局变量和函数,只能在本源文件中使用,对其它源文件不可见,即使使
用了extern关键字声明了该变量或函数也不行。
#include <stdio.h>
static int a = 10;
int main(void)
{
return 0;
}
readelf命令后,得到如下内容:
$ readelf -a test
43: 0000000000601018 4 OBJECT LOCAL DEFAULT 25 a
可以看到变量a有个LOCAL符号,去掉static关键字后,会变成GLOBAL符号,这样才能被其它目标文件链接到。