C 带位字段的结构偏移
我有一个关于获取结构中某个字段的索引偏移量的问题,下面是我用来测试的代码:C 带位字段的结构偏移,c,data-structures,bit-fields,C,Data Structures,Bit Fields,我有一个关于获取结构中某个字段的索引偏移量的问题,下面是我用来测试的代码: #include <stdio.h> typedef struct ipv4_pkt_struct { /*ethernet hdr*/ unsigned char DestMacAddr[6] ; unsigned char SrcMacAddr[6] ; unsigned char EthernetType[2] ; /*
#include <stdio.h>
typedef struct ipv4_pkt_struct
{
/*ethernet hdr*/
unsigned char DestMacAddr[6] ;
unsigned char SrcMacAddr[6] ;
unsigned char EthernetType[2] ;
/*IP hdr*/
unsigned char Version :4;
unsigned char IHL :4;
unsigned char TypeofService[2] ;
unsigned char Total_Length[4] ;
} ipv4_pkt_struct_t;
int main()
{
ipv4_pkt_struct_t A;
printf ("%d\n",(unsigned char*)A.TypeofService - (unsigned char*)A.DestMacAddr) ;
printf("Hello World");
return 0;
}
这是正确的,但是如果我做了以下事情:
printf ("%d\n",(unsigned char*)A.IHL - (unsigned char*)A.DestMacAddr) ;
它将给我一个非常有线的输出:
1296908304
Hello World
及
给出一个编译错误:
main.c: In function 'main':
main.c:29:5: error: cannot take address of bit-field 'IHL'
printf ("%d\n",(unsigned char*)&A.IHL - (unsigned char*)A.DestMacAddr) ;
如何获得正确的偏移量?您正在将未初始化的无符号字符强制转换为指针;此外,访问未初始化的数据是未定义的行为,即使您对其进行了初始化,也会使用值而不是这些值所在的地址进行计算
我建议使用,这正是为您的用例而构建的。在C位字段中,成员是不可寻址的 n1570-§6.5.3.2 p1: 一元运算符和运算符的操作数应为函数指示符、[]或一元运算符*的结果,或为指定非位字段[…]的对象的左值 除此之外,这条线
printf ("%d\n",(unsigned char*)A.TypeofService - (unsigned char*)A.DestMacAddr) ;
应该是
printf ("%td\n", A.TypeofService - A.DestMacAddr) ;
unsigned char*A.IHL-您正在将字符强制转换为指针。您希望得到什么?在所有情况下都必须使用变量的地址。使用unsigned char*&A.IHL代替unsigned char*&A.IHL。并考虑使用…获取结构中字段的偏移量。您希望偏移量的值是多少?14.5字节?偏移量只能是整数值。这没有道理。您无法获取位字段的地址,因此无法计算位字段成员的偏移量。永远不要使用位字段。请注意:如果您通过网络传输结构,或者说在进程之外,您可能还需要添加_属性_packed。IIRC,offsetof不能与位字段一起使用。操作员的地址也不能作为OP在更新问题中使用的地址。
printf ("%d\n",(unsigned char*)A.TypeofService - (unsigned char*)A.DestMacAddr) ;
printf ("%td\n", A.TypeofService - A.DestMacAddr) ;