与包含的类型相比,C++ 中的数组如何对齐?

问题描述 投票:0回答:5

假设我有某种类型

T
必须是
N
字节对齐。现在我声明一个类型为
T
:

的数组
T array[size];

阵列是否具有与类型

T
相同的对齐要求,还是有任何其他对齐要求?

c++ arrays
5个回答
20
投票

是的,对齐要求必须相同。显然,

T
数组必须至少与单个
T
一样严格对齐,否则其第一个成员将无法正确对齐。事实上,数组的对齐方式不能比其元素类型更严格,这一事实源自标准第 8.3.4 节,其中指出数组是“连续”分配的元素子对象。考虑这个数组数组: T a[2][size];

无论 
size

的值是什么,两个数组

a[0]
a[1]
之间不能有“额外”填充,否则这违反了
连续分配
要求。 同样,我们知道

(char*)&a[1] == (char*)&a[0] + sizeof(a[0])

sizeof(a[0]) == sizeof(T[size]) == size * sizeof(T)
。由于这适用于任何
size
,因此必须可以将
T
数组放置在与单个
T
对象适当对齐的任何地址(给定足够的地址空间)。
    


4
投票

显然,数组的开头必须至少与其第一个元素要求的严格对齐,因此其对齐要求不能不严格。

数组的起始地址加上每个元素的大小必须使第二个元素充分对齐。这对元素类型的大小施加了限制,我相信这意味着可以在结构的末尾引入填充,只是为了保持数组对齐,即使您从未在数组中使用该结构。但这并不意味着需要更严格的调整。

通过归纳,如果前两个元素都可以,那么后续元素也可以,因此为数组提供与其元素相同的对齐要求应该没问题。

不过,如果能引用规范就更好了。


1
投票

我相信,由于数组的每个元素都具有相同的大小,因此仅对齐第一个元素就会自动对齐其余元素,因此元素之间永远不会有任何填充。

对于简单数组来说这可能是正确的,但对于复杂场景则不然。

数组的步长可以大于元素大小,即每个单独元素之间可能有焊盘。

以下是一个很好的例子

struct ThreeBytesWide { char a[3]; }; struct ThreeBytesWide myArray[100];

 来源 - stride 维基百科

ThreeBytesWide 数组的每个元素都可以与四字节边界对齐

编辑:

正如评论中所述,提到在各个元素之间有焊盘是指元素本身为 3 个字节并与四字节边界对齐。


0
投票
C++ 数据成员对齐和数组打包

#include <iostream> __declspec(align(32)) struct Str1 { int a; char c; }; template<typename T> struct size { T arr[10]; }; int main() { size<Str1> b1; std::cout << sizeof(Str1) << std::endl; // prints 32 std::cout << sizeof(b1) << std::endl; // prints 320 std::cin.ignore(); return 0; }

参考资料:

    C++ 中的数据对齐、标准和可移植性
  1. http://msdn.microsoft.com/en-us/library/83ythb65.aspx

0
投票
的评论作为答案:

这里(用于对齐) §5.3.6 [expr.alignof] 1/

alignof
表达式产生其操作数类型的对齐要求。操作数应为表示完整对象类型或其数组的 type-id [...] 3/ [...] 当

alignof

 应用于数组类型时,结果应为元素类型的对齐方式.
具体来说,如果

alignof(array_type)
既是数组类型的对齐方式,又是元素类型的对齐方式,那么它们必须是相同的。

接受的答案中的参数与@Pubby
所述的

原因存在差距:对于固定长度的数组类型,为简单起见,说

T[N][M],其中N

是大于1的2的幂,编译器可以一致地为 
alignof(T)*N
T[N]
 选择 
T[N][M]
 对齐方式。为了填补这一空白,您必须争辩说,对于固定长度的数组类型,对齐不依赖于该固定长度。
有理由相信,如果违反该假设,那么 C++(或 C)实现将很难工作。例如,将指向固定长度数组的指针转换为指向较短数组的指针是有效的,这往往意味着它们应该具有相同的对齐方式。然而,这个论点也不起作用:因为通常在另一个方向上转换是无效的,即从较短的数组类型到较长的数组类型,这本身并不能排除后者可能具有更严格对齐的可能性.

无论如何,依赖关于

alignof

的直接陈述要简单得多,更有说服力。

© www.soinside.com 2019 - 2024. All rights reserved.