Henry
Henry

Reputation: 151

structure offset with bit field

I have a question on getting the index offset to a field in the structure, below is the code I use to test:

#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;
}

The output is:

15                                                                                                        
Hello World 

which is correct, but however if I do something like:

printf ("%d\n",(unsigned char*)A.IHL - (unsigned char*)A.DestMacAddr) ;

It will give me a very wired output:

1296908304                                                                                              
Hello World

and

printf ("%d\n",(unsigned char*)&A.IHL - (unsigned char*)A.DestMacAddr) ;

give an compile error:

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

how can I get the correct offset ?

Upvotes: 2

Views: 1629

Answers (2)

haccks
haccks

Reputation: 106022

In C bit field members are not addressable.

n1570-§6.5.3.2 (p1):

The operand of the unary & operator shall be either a function designator, the result of a [] or unary *operator, or an lvalue that designates an object that is not a bit-field [...]

Apart from that the line

printf ("%d\n",(unsigned char*)A.TypeofService - (unsigned char*)A.DestMacAddr) ;  

should be

printf ("%td\n", A.TypeofService - A.DestMacAddr) ;

Upvotes: 3

Stephan Lechner
Stephan Lechner

Reputation: 35154

You are casting an (uninitialized) unsigned char to a pointer; besides that accessing uninitialized data is undefined behaviour, even if you initialize it, you calculate with values and not with the addresses where these values reside.

I'd suggest to use offsetof, which is build for exactly your usecase.

Upvotes: 1

Related Questions