sizeof(T[N])是否保证等于N * sizeof(T)?

9

我一直认为,由sizeof返回的类型为T、元素数量为N的数组大小保证是恰好N乘以sizeof(T)

然而,在这个问题的评论区中,有声称数组可能包含填充的知名用户,这将破坏相等性。当然,这样的平台可能不存在,但它们是否被允许呢?

如果允许这样做,将会破坏许多常见的习语,例如使用N * sizeof(T)计算数组所需的存储空间,或使用sizeof(a)/sizeof(a[0])计算数组中元素的数量。


1
@AsadSaeeduddin - 正确的,我不认为我暗示了其他的意思?或者这是对一个现在已被删除的评论的回复。 - BeeOnRope
我在评论你链接的线程中的讨论。也许在某些运行时,数组占用的空间比它们的元素大小之和更大,但这与 sizeof(T[N])N * sizeof(T) 的事实无关。 - Asad Saeeduddin
@AsadSaeeduddin 同意。 - BeeOnRope
1
感谢您的提问,我有机会阅读了sizeof文档,http://en.cppreference.com/w/cpp/language/sizeof,在注释部分中,他们提到当sizeof应用于类类型时,其结果将包括插入该对象到数组所需的额外填充。 - Hải Phạm Lê
1
数组不能包含除每个单独元素末尾的填充之外的任何填充,该填充已包含在sizeof(element)中。 - n. m.
显示剩余2条评论
2个回答

11

是的。 [expr.sizeof] 包含了关于 sizeof 的这一点:

当应用于数组时,结果是数组中所有字节的总数。这意味着包含 n 个元素的数组的大小是每个元素的大小乘以 n


问题是,我不知道“数组中总字节数”的定义在哪里,而且我认为语句“This implies…”是错误的;我认为标准中没有这个语句也不意味着末尾没有隐式填充。如果我的理解是正确的,那么问题就是这个句子是否等同于“保证n元素的数组大小是元素大小的n倍”,还是只是标准中的一个问题。 - Daniel H
@DanielH 当然是真的,数组末尾没有填充。标准中也没有提到可能存在这样的填充。"数组类型的对象包含一个连续分配的非空T类型的N个子对象集合。" 没有更多了。只有类类型可能有填充字节。 - n. m.
如果你按照“当然”的方式去做,很快就会出现未定义行为。现在你指出那句话,我记得看到过,但人们不确定它是否必须仅包含那些内容。 - Daniel H
1
@DanielH标准多次提到数组的大小是其元素大小乘以元素个数。这个答案引用了其中一个提到的地方,还有其他的。无论它们是否具有法律规范性,我并不真的在意。这显然是意图,不亚于实际措辞的重要性。 - n. m.

2
< p > sizeof 的整个意义在于它包含了相关的填充。数组的每个元素都恰好比前一个元素多sizeof(T)字节。因此,整个数组的大小为N * sizeof(T)


1
我认为问题在于 sizeof(T) 是否允许仅针对数组的额外填充。所有单独的对象都有填充,但标准是否允许数组本身具有超出元素填充之外的填充? - Daniel H
那个额外的填充是从哪里来的? - Lily Ballard
编译器提示 sizeof(T[N]) > N * sizeof(T),因此在末尾添加了额外的填充。C++标准对布局没有太多规定,只要额外的填充保持了T[N]的对齐要求,这些要求至少需要与T相同(我认为必须完全相同,但我不确定),那么就是允许的。 - Daniel H
1
@DanielH 当讨论 sizeof 时,标准规定类类型的末尾可能会添加填充,并且为了将这些类型的对象放置在数组中,包括此填充在内的大小也会计入。在下一句话中,它讨论了应用于数组类型的 sizeof,并且没有说这些数组类型的末尾可能会添加填充(这就是 @melpomene 引用的内容)。为什么要发明标准从未提到的东西呢? - n. m.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接