C ++基元类型的对齐和大小

时间:2016-08-12 11:19:35

标签: c++ memory-alignment alignof

在C ++中,对于所有整数类型(intlong long intstd::uint16_t,...),对于浮点类型,似乎总是{{1} }。

这个编译器/平台是特定的,还是保证是真的?是否存在sizeof(T) == alignof(T)不需要在32位边界上对齐的平台(只要它们不重叠)?

1 个答案:

答案 0 :(得分:9)

对于基本类型,alignof(T) == sizeof(T)适用于大多数现代ABI,但不能保证是真的。 C ++标准使得对齐主要是实现定义的,仅受这些约束(参见C ++ 11中的 [basic.align] [basic.fundamental] ):< / p>

  • alignof(T) <= sizeof(T)。这在标准中并不明确,但是数组的元素之间从不存在任何填充,因此无论T t[2]的第一个元素的对齐如何, second 元素都不能对齐大于sizeof(T),因此这是 type T的最大对齐。请注意,变量的对齐可能更大,例如{{1}用在它上面。

  • alignas,但可能存在alignof(T) <= alignof(std::max_align_t)alignas是否会导致&#34;过度排列&#34; (比alignas更大的粒度)是实现定义的。

  • max_align_tcharsigned char都具有相同的对齐要求(即1,因为根据定义unsigned char。)

  • 所有无符号整数类型与对应的签名类型具有相同的对齐要求。

  • sizeof(char) == 1wchar_tchar16_t与&#34;基础&#34;具有相同的对齐要求整数类型。

是历史ABI,基本类型与其大小不一致。一个众所周知的例子是80386的原始System V ABI中的char32_tdouble,尽管分别为8和12字节宽,但它们仅与4字节粒度对齐。这是因为堆栈指针仅保证与4字节粒度对齐,并且很难将激活记录中的内容与堆栈指针的粒度对齐。 1

如今,同样的堆栈对齐问题可能会出现矢量类型;例如,在x86-64上,保证堆栈指针与16字节边界对齐,但硬件现在最多支持512-bit (64-byte) vectors

这是我个人所知的唯一反例。但是,我不会感到惊讶的是,对于内存受限的嵌入式环境,ABI为任何指定 no 对齐(即long double为所有人T)。它不像过去那样难以处理CPU,特别是如果没有涉及内存虚拟化的话。

1 有趣的事实:C ++标准要求实现具有函数调用堆栈。它需要支持递归,并且有一些叫做&#34;堆栈展开的东西&#34;抛出异常时会发生这种情况,但所有内容都经过精心编写,以便可以使用我们熟悉的线性堆栈之外的其他东西来实现它。