堆栈变量是否由GCC __attribute __((aligned(x)))对齐?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (36)

我有以下代码:

#include <stdio.h>

int
main(void)
{
        float a[4] __attribute__((aligned(0x1000))) = {1.0, 2.0, 3.0, 4.0};
        printf("%p %p %p %p\n", &a[0], &a[1], &a[2], &a[3]);
}

我有以下输出:

0x7fffbfcd2da0 0x7fffbfcd2da4 0x7fffbfcd2da8 0x7fffbfcd2dac

为什么地址a[0]不是多个0x1000

究竟__attribute__((aligned(x)))是什么?我误解了这个解释?

我正在使用gcc 4.1.2。

提问于
用户回答回答于

我相信问题在于你的数组在栈中。因为堆栈指针可能是函数启动时的任何东西,所以没有办法对齐数组,而不分配比需要更多的东西并调整它。如果将数组移出函数并将其转换为全局变量,它应该可以工作。你可以做的另一件事是保持它作为一个局部变量(这是一件很好的事情),但做到这一点static。这将防止它被存储在堆栈上。注意这两种方式都不是线程安全的或者是递归安全的,因为只有一个数组副本。

使用此代码:

#include <stdio.h>

float a[4] __attribute__((aligned(0x1000))) = {1.0, 2.0, 3.0, 4.0};

int
main(void)
{
        printf("%p %p %p %p\n", &a[0], &a[1], &a[2], &a[3]);
}

我得到这个:

0x804c000 0x804c004 0x804c008 0x804c00c

这是预期的。用你的原始代码,我只是得到像你一样的随机值。

用户回答回答于

gcc中存在一个导致属性对齐的错误,无法用于堆栈变量。它似乎与下面链接的补丁修复。下面的链接也包含了相当多的关于这个问题的讨论。

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16660

我已经使用两个不同版本的gcc:RedHat 5.7框中的4.1.2版尝试了上面的代码,它的失败类似于您的问题(本地阵列不会与0x1000字节边界对齐)。然后,我在RedHat 6.3上用gcc 4.4.6试了你的代码,并且它工作得很完美(本地数组是对齐的)。神话电视人有类似的问题(上面的海湾合作委员会补丁似乎修复):

http://code.mythtv.org/trac/ticket/6535

无论如何,它看起来像你在gcc中发现了一个bug,似乎在更高版本中被修复。

扫码关注云+社区

领取腾讯云代金券