Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 带位字段的结构偏移_C_Data Structures_Bit Fields - Fatal编程技术网

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) ;