#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));
}
当使用pragma pack时,以下程序的输出为16,但在使用pragma pack时为10.请解释这是怎么回事?
答案 0 :(得分:5)
首先,#pragma
是特定于编译器的,所以如果不指定编译器和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
};
因为打包是“2”,并且已经使用了[0]到[8]中的9个字节,所以sizeof(a)
被舍入到10。
没有你的编译指示,默认值是4字节/ 32位。因此,第一个int
在32位地址上对齐,以便更快地访问,跳过2和3并占用字节4,5,6,7。这将e
推送到这两个跳过的字节在字节9中,:0
强制后面的字段在字节12中。然后将总大小四舍五入为32位字大小,因此从13(对于字节[0]到[12]),向上到16岁。
答案 1 :(得分:4)
#pragma pack(2)
的效果纯粹是实现定义的,所以
你真的应该阅读有关它的文档(但我可以
猜测)。没有pragma,根据标准,存在
非位域元素或大小为0的位域会导致编译器
前进到下一个“单位”,因此在您的结构中,a
和b
位于
第一个单元,第二个单元c
,第三单元d
和e
,以及f
第四。鉴于大小是16,我猜4个字节单位(即
今天几乎普遍)。使用#pragma pack(2)
,我猜是的
基本单位是两个字节,而不是四个。而这并没有改变
int
的大小,因此c
仍然是四个字节,但其他单位
以上只有两个。这总共给出了十个字节,所以我的猜测
可能并不太远。