使用位域输出结构大小

use*_*457 1 c c++

#pragma pack(2)
struct a{
  unsigned a:1;
  unsigned b:1;
  int c;
  unsigned d:4;
  unsigned :4;
  unsigned e:1;
  unsigned :0;
  unsigned f:1;} ;

int main()
{
    printf("%d",sizeof(struct a));
}
Run Code Online (Sandbox Code Playgroud)

以下程序的输出在未使用pragma pack时为16,但在使用pragma pack时为10.请解释这是怎么回事?

Ton*_*roy 5

首先,#pragmas是编译器特定的,所以如果没有指定编译器和CPU(可能还有编译器版本和命令行选项),我们只能推测.

但是,一个似是而非的解释是,对于"pack(2)"版本:

#pragma pack(2)
struct a{ 
    unsigned a:1;    // at byte offset 0, could be least- or most-significant bit
    unsigned b:1;    // also in byte 0, besides a
    int c;           // explicitly requested this int be mis-aligned at byte 2
                     //   seems you've 32-bit ints, so 4-byte are 2,3,4,5
    unsigned d:4;    // at byte 6
    unsigned :4;     // also fits in byte 6
    unsigned e:1;    // in byte 7
    unsigned :0;     // requests following field be aligned for unsigned type
                     //   your unsigned int must be 32-bits, so this means
                     //   following field must start at 0, 4, 8, 12 etc.
                     //   so: skips rest of byte 7 and moves to 8
    unsigned f:1;    // occupies one bit of byte 8
};
Run Code Online (Sandbox Code Playgroud)

因为打包是"2",并且已经使用了从[0]到[8]的9个字节,所以它sizeof(a)被舍入到10.

没有你的pragma,默认值是4字节/ 32位.因此,第一个int是在32位地址上对齐以便更快地访问,跳过2和3并占用字节4,5,6,7.这会将e这2个跳过的字节推进到字节9中,并:0强制执行以下字段然后将总大小四舍五入为32位字大小,因此从13(对于字节[0]到[12]),最多为16.