我在其他帖子中写过这个问题。虽然情况并非如此。
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
非常感谢任何帮助。
答案 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
的评论中找到一些详细信息
但这适用于铿锵声。 clang的行为是改变sizeof
新类型以包括所需的对齐方式。
我认为这是一个GCC错误并提交了错误报告70407。