指针转换是否保持对齐属性?

时间:2019-05-21 14:23:36

标签: c++ pointers memory alignment language-lawyer

说,我有一个对齐的数组

alignas(X) char arr[sizeof(X)];

是指针

X * ptr = reinterpret_cast<X*>(arr);

可以保证根据X的对齐要求正确对齐吗?

似乎确实是这种情况,但是从C ++标准看来似乎并不明显。

我在标准中找不到阻止编译器对齐形式的结构的任何内容

struct X
{
    int16_t a;
    int32_t b;
    int16_t c;
};

在内存中像这样:

+-+-+-+-+-+-+-+-+
|a|a|b|b|b|b|c|c|
+-+-+-+-+-+-+-+-+
     ^
     aligned to 32-boundary

,以便X类型的对象以不需要填充的方式对齐,并且b同时正确对齐到32位边界。声明(N4713,第6.6.5.1节)

  

alignment 是实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数。

不会违反

,我在标准中也看不到任何违反它的声明。

2 个答案:

答案 0 :(得分:1)

您的结构应具有奇异的对齐方式:应为16位对齐,但不能为32位对齐。从数学上讲,其地址的格式应为32 * n +16,其中 n 是整数。

这是语言所禁止的,32位对齐方式应满足16位对齐方式。换句话说,任何16位对齐结构都应适合32位对齐存储区域,但16位对齐结构则不适合。参见[basic.align]/5

  

比对的顺序是从弱到强或从更严格的比对。更严格的比对具有更大的比对值。满足对齐要求的地址也满足任何较弱的有效对齐要求。

答案 1 :(得分:0)

该标准的作者并未试图明确禁止他们认为不可能的事情。如果一个编译单元包含的结构类似于您提供的结构:

struct {
  uint16_t a;
  uint32_t b;
  uint16_t c;
} x;

并且编译器对程序其余部分中可能使用x或具有相同布局的结构的所有方式都不了解,它只能选择偏移{{1} }是b的对齐方式的倍数。我不认为标准明确指出结构的布局不会受到使用方式的明显影响,但是我认为这是因为他们不认为编译器能够以这种方式改变布局维护通用初始序列保证。