【发布时间】:2019-05-22 13:45:30
【问题描述】:
说,我有一个对齐的数组
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)
对齐是实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数。
没有被违反,我在标准中没有看到任何其他违反它的声明。
【问题讨论】:
-
我对这个问题感到困惑,但也许我没有正确理解它。您是否在想象
X不包含填充但需要int32_t进行32 位对齐的场景?您是在问标准的哪一部分阻止了这种情况? -
我猜 alignas 是指从结构开始的内存对齐,与结构在内存中的实际位置无关。
-
@FrançoisAndrieux 是的,这正是我要问的。
-
@RalphTandetzky 我不确定标准中是否有明确的段落。它可能从其他语言规则中隐含,例如
X x; auto y = &x.b;需要生成指向b的可用指针这一事实,可能是语言如何定义运算符地址的定义的一部分。 -
如果结构的开头已经与 32 位边界对齐(例如来自
malloc或new),b将如何与 32 位边界对齐。b与 32 位对齐(在 8 位字节可寻址系统上)要求结构的开头与一个地址对齐,除以 4 时留下 2。
标签: c++ pointers memory alignment language-lawyer