简体   繁体   English

sizeof pragma packed bitfield struct array

[英]sizeof pragma packed bitfield struct array

I use Visual Studio 2013 for a x64 system. 我将Visual Studio 2013用于x64系统。 I have the following struct: 我有以下结构:

#pragma pack(1)
    struct TimeStruct
    {
      int milliseconds  : 10;
      BYTE seconds      : 6;    
      BYTE minutes      : 6;    
      BYTE hour         : 5;    
      BYTE day          : 5;    
    };
#pragma pack()

and an array: 和一个数组:

TimeStruct stArray[10];

When I use sizeof(stArray); 当我使用sizeof(stArray); I get 80 as a resault instead of 40. 我得到80作为一个突击而不是40。

I need to know if the problem is that the compiler doesn't pack correctly or if sizeof doesn't consider the bitfield's actual size. 我需要知道问题是编译器没有正确打包,或者sizeof是否考虑了位域的实际大小。

Thanks 谢谢

See What is VC++ doing when packing bitfields? 请参阅打包位域时VC ++正在做什么? for more explanation on how MSVC treats bitfields. 有关MSVC如何处理位域的更多解释。

It's implementation dependent how bitfields are packed and ordered, so be aware that the layout can be different from what you expect, and will depend on the particular compiler you are using. 它的实现依赖于如何打包和排序位域,因此请注意布局可能与您期望的不同,并且取决于您使用的特定编译器。

sizeof() gives you the size of the struct regardless of what its members are, so it's the bitfield packing that's different from your expectations. sizeof()为您提供结构的大小,无论其成员是什么,因此它的位域包装与您的期望不同。

You can possibly rason about the layout from the documentation or use this code to empirically discover the layout: 您可以从文档中了解布局或使用此代码来凭经验发现布局:

struct TimeStruct a;
unsigned char *b = (unsigned char*)&a;
a.milliseconds = 1;
a.seconds = 2;
a.minutes = 3;
a.hour = 3;
a.day = 4;
for(size_t i = 0; i < sizeof a; i++)
  printf("%02X ", b[i]);

 -> 64 bit compiler 01 00 00 00 02 03 04 05
 -> 32 bit compiler 01 30 FE 00 02 03 A4 65

It appears the struct is allocated an entire int for the 1. int milliseconds : 10; 似乎结构为1. int milliseconds : 10;分配了整个int int milliseconds : 10; member, and the remaining 3 bytes are packed individually after that, allocating a BYTE for each member, but not combining bits from the different allocated units. 成员,其余3个字节在此之后单独打包,为每个成员分配BYTE,但不组合来自不同分配单元的位。

You should be able to pack it tightly with the MSVC compiler if you use int or unsigned int for all the fields, and this struct will take 4 bytes: 如果对所有字段使用int或unsigned int,则应该能够使用MSVC编译器将其打包,并且此结构将占用4个字节:

struct TimeStruct
{
  int milliseconds : 10;
  int seconds      : 6;    
  int minutes      : 6;    
  int hour         : 5;    
  int day          : 5;    
};

Bit fields stored using the defined type like this. 使用如此定义的类型存储的位字段。

int milliseconds : 10; // 4 bytes
BYTE seconds      : 6; // 1 byte
BYTE minutes      : 6; // 1 byte
BYTE hour         : 5; // 1 byte
BYTE day          : 5; // 1 byte

This is how MSVC 2013 x64 stores it in the memory 这就是MSVC 2013 x64将其存储在内存中的方式

11111111 11000000 00000000 00000000
11111100 11111100 11111000 11111000

So, to sum up, you use 8 bytes to store one structure. 因此,总而言之,您使用8个字节来存储一个结构。 8x10 is 80 bytes. 8x10是80字节。 Everything is correct. 一切都是正确的。

It's worth mentioning that gcc behaves differently and allows more tight packing. 值得一提的是,gcc表现不同,允许更紧密的包装。

Here the difference between gcc and MSVC implementation is explained: Forcing unaligned bitfield packing in MSVC 这里解释了gcc和MSVC实现之间的区别: 在MSVC中强制未对齐的位域打包

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM