将类型包装在结构中会导致额外的填充吗?
可能的重复:
单个元素的结构大小
给定任何类型A
和以下结构:
struct S
{
A a;
};
是否存在 sizeof(S)
大于 sizeof(A)
的情况?
例如,sizeof(std::array
可以大于 sizeof(T[n])
吗?
Possible Duplicate:
Size of struct with a single element
Given any type A
and the following struct:
struct S
{
A a;
};
Are there any cases where sizeof(S)
is greater than sizeof(A)
?
For example, can sizeof(std::array<T, n>)
be greater than sizeof(T[n])
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
能够在 S 内部使用 A 意味着编译器已经了解 A 的结构,并且已经向其中添加了填充字节。我认为没有理由为 S 添加进一步的填充,因为它已经对齐了。
Being able to use A inside of S means that the compiler already has knowledge of the structure of A and has already added padding bytes to it. I see no reason for it to add further padding to S, as it already is aligned.
虽然结构可以被填充,但在我知道的所有系统上,编译器都会填充,以便结构的对齐方式与其成员的最大对齐方式相同。这样做是为了使结构数组始终正确对齐。
所以:
编辑:注意,编译器还可以添加内部填充,以保持数据的对齐正确。
C/C++ 标准没有指定任何这些细节。您想要的是您正在运行的系统的 C ABI(应用程序二进制接口),它应该指定结构的默认布局(编译器可以选择覆盖它,如果他们认为合适,另请参阅#pragma pack)。例如,请查看 X86_64 ABI 第 13 页,其中指出:
While the struct can be padded, on all systems I know, the compiler will pad so that the alignment of the structure is the same as the largest alignment of its members. It does this so that an array of the structure will always be correctly aligned.
So:
Edit: Note, that compilers can also add internal padding, to keep the alignment of the data correct.
The C/C++ standard doesn't specify any of these detail. What you want is the C ABI (application binary interface) for the system you're running on, which should specify default layout for structs (compilers can choose to override this if they see fit, see also #pragma pack). For an example, look at the X86_64 ABI page 13, which states:
相关文本是 5.3.3/2“当应用于类时,结果是该类的对象中的字节数,包括将该类型的对象放入数组中所需的任何填充。”
出于数组边界检查的目的,实现可以添加额外的字节(例如
“这是总共 12 个数组成员中的第 5 个”
,因为这是在此处授予的余地内且未明确指定) (据推测,该实现还会为不属于数组的结构存储“1 of 1”指示;在 C++ 中,类型
S
和S [1]
是相当可互换)The relevant text is 5.3.3/2 "When applied to a class, the result is the number of bytes in an object of that class including any padding required for placing objects of that type in an array."
An implementation is allowed to add extra bytes for the purposes of array bound checks (e.g.
"this is the 5th array member out of a total of 12"
, as this is within the leeway granted here and not explicitly banned by any other requirement.(Presumably, that implementation would also store a "1 out of 1" indication for structs that aren't part of an array; in C++ the types
S
andS[1]
are quite interchangable)ISO/IEC 14882(10/2008) 1.8.5:
这意味着空结构的大小为1,尽管“所有数据成员”(没有)的大小为零,零长度位字段也是如此(根据9.6.2,这将是不过,必须是未命名位字段)。
但这两种情况都没有真正适用,因为您没有要求一个空结构,并且您的成员已命名(因此它不能是零长度)。
如果您的
a
成员的类型为void
,情况也是如此,但 3.9.5 不允许这样做("[.. .] void 类型是不完整类型(3.9.1)。对象不应被定义为具有不完整类型”)。简而言之,正如您所说,您最感兴趣的是标准的内容:不,标准没有明确定义这种情况。
但是,它也不禁止编译器添加填充或应用对齐,并且大多数编译器默认情况下会根据机器字大小填充/对齐结构(除非另有明确说明)。
ISO/IEC 14882(10/2008) 1.8.5:
This means that an empty struct has a size of 1 although the size of "all data members" (there are none) is zero, as would a zero-length bitfield (according to 9.6.2 this would have to be an unnamed bitfield, though).
Neither really applies though, as you did not ask for an empty struct, and your member is named (so it can't be zero-length).
Similar would be true if your
a
member was of typevoid
, but 3.9.5 does not allow that ("[...] the void types are incomplete types (3.9.1). Objects shall not be defined to have an incomplete type").So in short, as you said you are mostly interested about what the standard says: no, the standard does not explicitly define such a case.
However, it also does not forbid the compiler to add padding or apply alignment, and most compilers will pad/align structures to machine word size by default (unless explicitly told otherwise).
结构可以被填充(编译器可以做任何他们喜欢的事情,例如将六个八位字节类型填充到八个八位字节以与页面边界对齐)。但这不太可能发生。
std::array 将会更大,因为它在类中存储了一些额外的信息,例如数组的长度。自动驾驶;不假思索地阅读 std::vector 。A struct can be padded (it's allowed for compilers do whatever they like, for example padding a six-octet type to eight to align with page boundaries). It's unlikely to happen though.
std::array will be bigger, because it stores some extra information in the class, like the array's length.Typing on auto-pilot; read std::vector without thinking.如果 A 是一个字节,则结构将与最近的边界对齐。相反,如果 A 小于边界,那么它会更大。 EX RGB 结构与 RGBA 结构大小相同。
我没有可以做到这一点的示例代码。您必须转储内存并查看漏洞。如果您假设所有内容都大小对齐并将结构投射到一叠内存上,那么您将得到错误的数据。这就是 WAD 具有用于对齐的填充的原因。随着您的组合变得更加复杂,编译器弥补漏洞的能力就会减弱。最终将引入填充,并且任何内存布局的假设都将变得越来越错误。
If A is a byte then struct will align to the nearest boundary. Rather if A is smaller than a boundary then yes it will be bigger. EX a struct of RGB is the same size as a struct of RGBA.
I don't have sample code that will do that. You have to dump memory and see the holes. If you then assume that everything is size aligned and cast a structure onto a wad of memory you will have bad data. This is why WADs had padding for alignment. As your compositions get more complicated, the ability to close holes by the compiler is diminished. Eventually padding will be introduced and any assumptions of memory layout will become more and more wrong.