在C ++中,对于所有整数类型(int
,long long int
,std::uint16_t
,...),对于浮点类型,似乎总是{{1} }。
这个编译器/平台是特定的,还是保证是真的?是否存在sizeof(T) == alignof(T)
不需要在32位边界上对齐的平台(只要它们不重叠)?
答案 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_t
,char
和signed char
都具有相同的对齐要求(即1,因为根据定义unsigned char
。)
所有无符号整数类型与对应的签名类型具有相同的对齐要求。
sizeof(char) == 1
,wchar_t
和char16_t
与&#34;基础&#34;具有相同的对齐要求整数类型。
是历史ABI,基本类型与其大小不一致。一个众所周知的例子是80386的原始System V ABI中的char32_t
和double
,尽管分别为8和12字节宽,但它们仅与4字节粒度对齐。这是因为堆栈指针仅保证与4字节粒度对齐,并且很难将激活记录中的内容与堆栈指针的粒度对齐。 1
如今,同样的堆栈对齐问题可能会出现矢量类型;例如,在x86-64上,保证堆栈指针与16字节边界对齐,但硬件现在最多支持512-bit (64-byte) vectors。
这是我个人所知的唯一反例。但是,我不会感到惊讶的是,对于内存受限的嵌入式环境,ABI为任何指定 no 对齐(即long double
为所有人T)。它不像过去那样难以处理CPU,特别是如果没有涉及内存虚拟化的话。
1 有趣的事实:C ++标准不要求实现具有函数调用堆栈。它需要支持递归,并且有一些叫做&#34;堆栈展开的东西&#34;抛出异常时会发生这种情况,但所有内容都经过精心编写,以便可以使用我们熟悉的线性堆栈之外的其他东西来实现它。