通过一个例子说明C语言如何初始化静态变量。
给出C语言代码
typedef int (* Fun)(void * obj, int argc, int *argv);
struct FunctionSpec {
const char *name; /* 8 */
Fun call; /* 8 */
unsigned char nargs; /* 1 */
unsigned char flags; /* 1 */
unsigned short extra; /* 2 */
};
static int foo1(void *obj, int argc, int *argv)
{
return 0;
}
static int foo2(void *obj, int argc, int *argv)
{
return 0;
}
static int foo3(void *obj, int argc, int *argv)
{
return 0;
}
static struct FunctionSpec my_functions[] = {
{"foo1", foo1, 11, 22, 33},
{"foo2", foo2, 44, 55},
{"foo3", foo3, 66},
{0}
};
int main(int argc, char * argv[])
{
printf("sizeof FunctionSpec=%d\n", sizeof(struct FunctionSpec));
printf("sizeof my_functions=%d\n", sizeof(my_functions));
return 0;
}
我们定义了一个 数组变量my_functions,数组类型是struct FunctionSpec。
struct FunctionSpec包含5个成员变量,但是在初始化的时候有些成员提供了5个值,而有些只提供了4个值,或者三个值;那么剩下没有提供值得域会怎么处理呢,gcc编译器会为他们赋初始零值。
(下来过程在linux x86_64环境下完成)
1. 编译
$ gcc test.c
2. 运行
$ ./a.out
sizeof FunctionSpec=24
sizeof my_functions=96
structure FunctionSpec共有5个域,前两个域是指针类型各自占用8字节长度,第3和第4域是字符类型各自占用一个字节长度,第5个域是short类型占用两个字节长度。但是需要字节对齐,整个结构需要占用24字节长度(此例子中,只需要在结尾padd四个字节即可)。
3. 查看my_functions的汇报代码
在Linux x86_64环境下运行结果:
sizeof FunctionSpec=24
sizeof my_functions=96
查看汇编代码对static变量my_functions的空间分配
.section .rodata
.LC0:
.string "foo1"
.LC1:
.string "foo2"
.data
.align 32
.type my_functions, @object
.size my_functions, 96
my_functions:
.quad .LC0 # 第一个元素: 8 字节指针指向字符串foo1的地址
.quad foo1 # 8 字节指针指向函数foo1的地址
.byte 11 # 1 字节参数nargs的值
.byte 22 # 1 字节参数flags的值
.value 33 # 1 字节参数extra的值
.zero 4 # 4 字节的padd, 和前面4字节构成一个8字节的标准长度
.quad .LC1 # 第二个元素: 8 字节指针指向字符串foo2的地址
.quad foo2 # 8 字节指针指向函数foo2的地址
.byte 44 # 1 字节参数nargs的值
.byte 55 # 1 字节参数flags的值
.zero 6 # 6 字节的padd, 和前面2字节构成一个8字节的标准长度, 因为这个元素只给参数nargs和flags赋了值,剩下参数是0
.quad .LC2 # 第二个元素: 8 字节指针指向字符串foo3的地址
.quad foo3 # 8 字节指针指向函数foo3的地址
.byte 66 # 1 字节参数nargs的值
.zero 7 # 7 字节的padd, 和前面2字节构成一个8字节的标准长度, 因为这个元素只给参数nargs赋了值,剩下参数都是0
.quad 0 # 第三个元素
.zero 16 # 所有的参数都是缺省值0
.section .rodata
ddd
4. the end