gpt4 book ai didi

c - 为什么GCC会为不同作用域的local union分配单独的栈空间?

转载 作者:太空狗 更新时间:2023-10-29 17:10:13 27 4
gpt4 key购买 nike

考虑以下代码:

#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;
}

按原样为 x86 编译(意味着 testme 是一个结构),编译器为 main 分配的堆栈大小为 16 字节。

$ gcc -g -O2 test.c -o test 
$ objdump -d ./test | ./checkstack.pl i386 | grep main
16 main

然而,编译时定义为 union 的 TRY(意思是 testme 是一个 union ),编译器分配给 main 的堆栈大小是 32 字节:

$ gcc -DTRY=union -g -O2 test.c -o test 
$ objdump -d ./test | ./checkstack.pl i386 | grep main

此外,在附加作用域中定义的结构/union 的任何附加实例在使用 union 时会产生更大的堆栈分配,但在用作结构时不会扩大堆栈分配。

现在,这没有意义 - union 应该占用更少的堆栈空间,如果有的话,而不是更多,然后是具有相同字段的结构!

似乎 GCC 将 union 视为并发使用,即使在不同的范围内也是如此,但对于结构则不同。

更多说明:

  1. volatile 用于阻止编译器优化赋值。放弃 volatile 和不进行优化的编译会产生相同的结果。

  2. 即使 testme 是一个以 union 作为成员之一的结构,也会观察到相同的行为。换句话说 - 一个结构的成员之一是 GCC 用于单独堆栈分配的 union 就足够了。

  3. 编译器是 gcc 版本 4.4.3 (Ubuntu 4.4.3-4ubuntu5),但其他架构的其他 GCC 版本显示相同的行为。

  4. checkstack.pl 只是在 objdump 输出中搜索用于分配堆栈(子堆栈指针)的指令。

我的问题:

  1. 为什么 GCC 这样做?这是错误还是这种行为有原因?
  2. 假设这不是错误,是否有办法解决这个问题并强制 GCC 为与 union 相同的结构分配堆栈。

澄清:我的问题不是为什么结构或 union 的大小从其部分的大小来看似乎更大。我知道原因是为了对齐而填充。我的问题是编译器为 union 的不同实例分配多个堆栈帧,即使它们是在不同的范围内定义的,但它不应该而且实际上不会为具有相同字段的结构做同样的事情。

谢谢!

最佳答案

显然,至少已经尝试放松 gcc 关于 union 的严格别名妄想症。

您可能希望确保您编译的 gcc 源代码应用了这个或等效的补丁: http://codereview.appspot.com/4444051/

关于c - 为什么GCC会为不同作用域的local union分配单独的栈空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9390875/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com