gby*_*gby 7 c stack gcc stack-size
请考虑以下代码:
#include <stdlib.h>
#ifndef TRY
#define TRY struct
#endif
TRY testme
{
int one;
int two;
char three;
int four;
};
int
main (void)
{
{
volatile TRY testme one;
one.one = 2;
one.three = 7;
}
{
volatile TRY testme twos;
twos.one = 3;
}
{
volatile TRY testme one;
one.one = 4;
}
{
volatile TRY testme twos;
twos.one = 5;
}
{
volatile TRY testme twos;
twos.one = 6;
}
{
volatile TRY testme twos;
twos.one = 6;
}
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
编译为x86是(意味着testme是一个结构),编译器为main分配的堆栈大小是16个字节.
$ gcc -g -O2 test.c -o test
$ objdump -d ./test | ./checkstack.pl i386 | grep main
16 main
Run Code Online (Sandbox Code Playgroud)
但是,使用TRY定义为union(意思是testme是一个union)编译,编译器为main分配的堆栈大小为32字节:
$ gcc -DTRY=union -g -O2 test.c -o test
$ objdump -d ./test | ./checkstack.pl i386 | grep main
Run Code Online (Sandbox Code Playgroud)
此外,在其他范围中定义的struct/union的任何其他实例在使用union时将产生更大的堆栈分配,但在用作struct时不会扩大堆栈分配.
现在,这没有意义 - 联合应该占用更少的堆栈空间,如果有的话,不是更多,然后是具有相同字段的结构!
似乎GCC将工会视为同时使用,即使在不同的范围内,但结构也不同.
更多澄清:
volatile用于阻止编译器优化分配.在没有优化的情况下松开volatile并进行编译会产生相同的结果.
即使testme是一个具有union作为成员之一的结构,也会观察到相同的行为.换句话说 - 结构的一个成员是GCC的联合就足以进行单独的堆栈分配就足够了.
编译器是gcc版本4.4.3(Ubuntu 4.4.3-4ubuntu5),但其他架构的其他GCC版本显示了相同的行为.
checkstack.pl只是在objdump输出中搜索用于分配堆栈的指令(sub到堆栈指针).
我的问题:
澄清:我的问题不是为什么结构或联合体的大小与其部分的大小相比更大.我理解原因是填充对齐.我的问题是编译器为联合的不同实例分配了多个堆栈帧,即使它们在不同的范围内定义,而它不应该,并且对于具有相同字段的结构实际上不会这样做.
谢谢!