sizeof pragma packed bitfield struct array

时间:2015-01-22 14:22:57

标签: c++ visual-studio-2012 sizeof pragma bit-fields

我将Visual Studio 2013用于x64系统。 我有以下结构:

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

和一个数组:

TimeStruct stArray[10];

当我使用sizeof(stArray);时,我得到的是80而不是40。

我需要知道问题是编译器没有正确打包,或者sizeof是否考虑了位域的实际大小。

由于

2 个答案:

答案 0 :(得分:4)

有关MSVC如何处理位域的更多说明,请参阅What is VC++ doing when packing bitfields?

它的实现依赖于如何打包和排序位域,因此请注意布局可能与您期望的不同,并且取决于您使用的特定编译器。

sizeof()为您提供结构的大小,无论其成员是什么,因此它的位域包装与您的期望不同。

您可以从documentation浏览布局或使用此代码以经验方式发现布局:

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

看起来struct为1. int milliseconds : 10;成员分配了一个完整的int,剩下的3个字节在此之后单独打包,为每个成员分配一个BYTE,但不组合来自不同分配单元的位。

如果对所有字段使用int或unsigned int,则应该能够使用MSVC编译器将其打包,并且此结构将占用4个字节:

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

答案 1 :(得分:0)

使用定义的类型存储位字段。

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

这就是MSVC 2013 x64将其存储在内存中的方式

11111111 11000000 00000000 00000000
11111100 11111100 11111000 11111000

因此,总而言之,您使用8个字节来存储一个结构。 8x10是80字节。一切都是正确的。

值得一提的是,gcc表现不同,允许更紧密的包装。

这里解释了gcc和MSVC实现之间的区别: Forcing unaligned bitfield packing in MSVC