结构的大小是否必须是该结构的对齐的精确倍数?

Ste*_*314 17 c++ struct sizeof alignment

我再一次质疑一个长期存在的信念.

直到今天,我相信以下结构的对齐通常为4,大小通常为5 ...

struct example
{
  int   m_Assume_32_Bits;
  char  m_Assume_8_Bit_Bytes;
};
Run Code Online (Sandbox Code Playgroud)

由于这个假设,我有数据结构代码使用offsetof来确定数组中两个相邻项之间的字节距离.今天,我发现了一些使用sizeof的旧代码,它本不应该,不明白为什么我没有错误,编写单元测试 - 测试让我感到惊讶.

一些调查显示我用于测试的类型的大小(类似于上面的结构)是对齐的精确倍数 - 即8个字节.它在最终成员之后有填充.这是一个为什么我从没想过这个的例子......

struct example2
{
  example m_Example;
  char    m_Why_Cant_This_Be_At_Offset_6_Bytes;
};
Run Code Online (Sandbox Code Playgroud)

一些谷歌搜索显示的例子清楚表明允许最后一个成员之后的填充 - 例如http://en.wikipedia.org/wiki/Data_structure_alignment#Data_structure_padding("或结构的末尾"位) .

这有点令人尴尬,因为我最近发布了这条评论 - 使用struct padding(我对该答案的第一个评论).

我似乎无法确定的是,这个填充到对齐的精确倍数是否由C++标准保证,或者它是否只是允许的内容以及某些(但可能不是全部)编译器.

那么 - 根据C++标准,结构的大小是否需要是该结构对齐的精确倍数?

如果C标准有不同的保证,我也对此感兴趣,但重点是C++.

APr*_*mer 17

5.3.3/2

应用于类时,[sizeof]的结果是该类对象中的字节数,包括在数组中放置该类型对象所需的任何填充.

所以是的,对象大小是其对齐的倍数.


Meh*_*dad 10

对齐大小的一个定义:

结构的对齐大小是当您拥有该结构的数组时从一个元素到下一个元素的偏移量.

就其性质而言,如果你有一个包含两个元素的结构数组,那么两者都需要有对齐的成员,这意味着是的,大小必须是对齐的倍数.(我不确定是否有任何标准明确强制执行此操作,但由于结构的大小和对齐不依赖于结构是单独还是数组内部,因此相同的规则适用于两者,因此它不能真正实现任何其他方式.)


Ben*_*igt 6

标准说(部分[dcl.array]:

数组类型的对象包含一个类型为T的连续分配的非空N个子对象集.

因此,数组元素之间没有填充.

标准不要求在结构内部填充,但标准不允许任何其他方式对齐数组元素.