我在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)的元素的正确解决方案是什么?
答案 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
功能,因为这会告诉你你的具体事实。