C中位域结构的大小

时间:2014-02-10 12:14:32

标签: c sizeof bit-fields

我在C中使用位精度字段表示IP头:

typedef struct __attribute__((packed)) {
    unsigned char __reserved : 1;
    unsigned char dont_fragment : 1;
    unsigned char more_fragment : 1;
    unsigned short fragment_offset : 13; // if fragmented, in 8 byte units from the start of the datagram
} ipv4_fragmenting;

我使用16位可以存储在2个字节上。那么为什么结构的大小(sizeof(ipv4_fragmenting))是4而不是2?

我的编译器:GCC 4.8.1

编辑:

如果位域特定于平台且打包属性不可靠,那么表示先前定义的协议(如IPv4)的元素的正确解决方案是什么?

4 个答案:

答案 0 :(得分:2)

就像我已经评论过的那样,对比特字段和结构大小进行推测是没有意义的,因为该语言并没有强制要求这个领域。

GCC 4.8.1的大小为4(假设是32位编译器);这可能是GCC 4.8.1的一个错误。我之前提出了question on SO,其中设置packed属性不能按预期工作,就像这里一样。对于仅使用#pragma pack工作的字节对齐打包。例如:

#include <stdio.h>

#pragma pack(push, 1)
typedef struct {
    unsigned char __reserved : 1;
    unsigned char dont_fragment : 1;
    unsigned char more_fragment : 1;
    unsigned short fragment_offset : 13; // if fragmented, in 8 byte units from the start of the datagram
} ipv4_fragmenting;
#pragma pack(pop)

int main()
{
    printf("%u\n", sizeof(ipv4_fragmenting));
}

这为我打印3,正如ILP32机器MinGW GCC 4.8.1所预期的那样。

答案 1 :(得分:1)

位字段存储取决于实现。您定义的字段可以填充(增加所需的存储空间)。

答案 2 :(得分:0)

在某些32位平台上,结构被填充为32位边界,例如。每4个字节。 在GCC上,我认为你可以在某些平台上控制它:Structure Packing Pragmas

答案 3 :(得分:0)

我一直都知道类型大小取决于实现和体系结构以及操作系统。我不认为这是一个错误。 无论如何,你必须信任你的sizeof功能,因为这会告诉你你的具体事实。