GCC __attribute __((aligned(8)))无效

时间:2016-03-28 11:31:19

标签: c gcc

我在其他帖子中写过这个问题。虽然情况并非如此。

  

GCC编译器版本:4.8.3(适用于ARM)

代码摘录:

uint8_t data[4] __attribute__ ((aligned (8))) = {1,2,3,4};

int main()
{
    uint32_t p = 0;
    p = (uint32_t)&data[0];
    p = (uint32_t)&data[1];
    p = (uint32_t)&data[2];
    p = (uint32_t)&data[3];
}

请注意数据超出任何功能,因此在堆栈中分配了 NOT

p我看到(调试时)的结果是:536870912, 536870913, 536870914, 536870915;

我期待这样的事情:536870912, 536870920, 536870928, 536870936

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

您告诉编译器在8字节边界上对齐数组每个成员。简单的答案是 - 你不能用标量数据类型来做,因为编译器不允许在数组元素之间放置任何填充(毕竟,*x++作为指向uint8_t的指针仍然应该仅将指针递增1)。

这样的东西
struct alignas(8) AL_BYTE{
   uint8_t theByte;
}
struct AL_BYTE data[4] __attribute__ ((aligned (8))) = {{.theByte=1},....

应该达到你想要的效果。

答案 1 :(得分:0)

我打赌aligned (..)分别对齐整个数组而不是每个项目。

据我所知,标准禁止数组元素之间的任何额外填充(数组大小==每个项目的大小*项目数量)。

如果希望每个元素按8字节边界对齐,则需要将元素设置为8字节大。

可能的解决方案(将它们与__attribute__ ((aligned (8)))合并):

  • 一组结构(struct {uint64_t byte, padding[7];};)。
  • uint64_t的数组(然后您需要确保仅使用每个数字的最低字节)。这只适用于lil-endian平台。
  • 一个uint8_t数组,比实际需要大8倍(同样,你需要确保只使用你需要的字节)。

答案 2 :(得分:-1)

一个可能的解决方案是typedef char与新类型对齐,然后从新类型中创建一个数组,遗憾的是在GCC中不起作用demoed here

typedef char AlignedChar __attribute__ ((aligned (8)));

AlignedChar test[16]={};

//prog.c:4:1: error: alignment of array elements is greater than element size

可以在this question

的评论中找到一些详细信息

但这适用于铿锵声。 clang的行为是改变sizeof新类型以包括所需的对齐方式。

我认为这是一个GCC错误并提交了错误报告70407