简体   繁体   English

为什么这个结构的大小是5,当它应该是4

[英]why size of this structure is 5 when it should be 4

I am trying to pack some data into a structure. 我试图将一些数据打包到一个结构中。

the structure definition is as follow: 结构定义如下:

#pragma pack(push)
#pragma pack(1)
struct Data
{
    unsigned char i:2;
    unsigned short r:14;
    unsigned short c:14;
};
#pragma pack(pop)

Since the number of bits are 30 and pack is one, My understanding is that the size of this structure should be 4, but the compiler says that the size of it is 5 byte. 由于位数是30而pack是1,我的理解是这个结构的大小应该是4,但是编译器说它的大小是5个字节。

I am using Visual Studio 2012. 我正在使用Visual Studio 2012。

Please note that they are bit fields. 请注意,它们是位字段。

This has the size of 4: 这个大小为4:

struct Data
{
    unsigned short i:2;
    unsigned short r:14;
    unsigned short c:14;
};

The exact layout of bitfields in memory is not specified by the standard. 内存中位域的确切布局未由标准指定。 However, I'm fairly convinced that if you use unsigned int for all your fields, like this: 但是,我相信如果你对所有字段使用unsigned int ,就像这样:

struct Data
{
    unsigned int i:2;
    unsigned int r:14;
    unsigned int c:14;
};

your data will be packed into one 30-bit integer value. 您的数据将打包成一个30位整数值。 However, since you have declared the first field a char, it can not hold a 14-bit value, and thus is seen as a separate field. 但是,由于您已将第一个字段声明为char,因此它不能保存14位值,因此被视为单独的字段。

(gcc gives 4 bytes for both variants, which is one reason I say that there are differences between compilers - hence nothing in the standard stating that the fields are not defined in the standard) (gcc为这两个变体提供了4个字节,这是我说编译器之间存在差异的一个原因 - 因此标准中没有说明标准中没有定义字段)

Because the pack pragma controls the alignment of the members. 因为pack pragma控制成员的对齐。 When you say 1 - it means the members are aligned at byte limits, ie a member can begin at every byte. 当你说1 - 它意味着成员在字节限制时对齐,即成员可以从每个字节开始。 But as you have 3 members of the size 1, 2, and 2 the resulting size is 5. If you not use it, the compiler uses usually a higher alignment than 1 as it is for the cpu far more efficient to access elements at multiple of certain values (in your case, as it occupies 6 bytes when removing the pack pragme). 但是由于你有3个大小为1,2和2的成员,结果大小为5.如果不使用它,编译器通常使用比1更高的对齐,因为它对于cpu而言更有效地访问多个元素某些值(在您的情况下,因为它在删除包pragme时占用6个字节)。

Pack is not a packing of the structure on bit level. Pack不是位级结构的打包。

EDIT : To clarify this statement a cite from the pack pragma doc from Visual Studio: 编辑 :澄清此声明来自Visual Studio的包编译指示文档中的引用:

n(optional): Specifies the value, in bytes, to be used for packing. n(可选):指定要用于打包的值(以字节为单位)。 The default value for n is 8. Valid values are 1, 2, 4, 8, and 16. The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller. n的默认值为8.有效值为1,2,4,8和16.成员的对齐将位于边界上,该边界是n的倍数或成员大小的倍数,以较小者为准更小

EDIT 2 (After edit from question): The reason why the bitfield in the first case get not merged (and show above behavior), is that Visual Studio only merges bitfield members of a structure into one data element, when they have the same dataype. 编辑2 (从问题编辑后):第一种情况下的位域未合并(并显示上述行为)的原因是Visual Studio只将结构的位域成员合并为一个数据元素,当它们具有相同的dataype时。 So when all are declared short, he tries to merge them (and is successful in this case), but when one is different he cant merge. 因此,当所有都被宣告为短时,他会尝试合并它们(并且在这种情况下是成功的),但是当一个不同时他就无法合并。

My understanding is that the elements are packed in groups of the same type. 我的理解是元素被打包成相同类型的组。 If you replace 'char' by 'short', it will pack the ':2' with the following ':14' because 16 bits fits on the 'short'. 如果你将'char'替换为'short',它将使用以下':14'打包':2',因为16位适合'short'。

The merge is not done if you have 'char' followed by 'short'. 如果您有'char'后跟'short',则不会合并。

Bitfields are weird beasts anyway :) Bitfields无论如何都是奇怪的野兽:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么使用24位整数时结构的大小不会改变 - why size of structure does not change when use 24 bit integer 为什么不应该以这种方式隐藏结构实现? - Why one should not hide a structure implementation that way? 使用gcc时,为什么打包结构的大小在Linux和Windows上会有所不同? - Why would the size of a packed structure be different on Linux and Windows when using gcc? 为什么sizeof(* node)给出结构的大小而不是指针的大小 - Why does sizeof(*node) give the size of the structure and not size of the pointer 为什么全局数组大小应该是整数常量? - Why should global array size be an integer constant? 为什么在 C 的以下代码中,结构指针 **s 的大小在取消引用到 '*s' 并进一步到 's' 时为 8? . 谁能解释一下 - Why is the size of structure pointer **s when derefenced to '*s' and further to 's' is 8 in the below code in C? . Can anybody please explain it 当大小已知时我应该使用构造函数吗 - Should I use a constructor when size is known 为什么在应输出4时输出5 - Why is it outputting 5 when it should output 4 什么时候/为什么要使用heapmin? - When/why should heapmin be used? 为什么? 更改构建结构后,可执行文件的大小显着减少 - Why? Executable size cuts dramatically after changing build structure
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM