3

Here is the structure I want:

typedef struct someip_header { 
    union { 
        uint32_t message_id;
        struct {
            uint16_t service_id; 
            uint8_t for_rpc : 1; 
            union {
                uint16_t method_id : 15;
                uint16_t event_id : 15;
            };
        };
    };
} someip_header_t;

(The reason is that if for_rpc is 1, then the last 15 bits mean event ID, otherwise they mean method ID)

But the size of this structure is 5 bytes (packed), I guess because the compiler won't put union unaligned. If I replace the inner union with just a uint16_t val : 15, the size gets back to 4 bytes as expected:

typedef struct someip_header { 
    union { 
        uint32_t message_id;
        struct {
            uint16_t service_id; 
            uint8_t for_rpc : 1; 
            uint16_t method_event_id : 15;
        };
    };
} someip_header_t;

Just wondering, is there a way to pack this? It's really only cosmetic, but still...

Pawel Veselov
  • 3,996
  • 7
  • 44
  • 62
  • 3
    While not being really my favorite thing, here MISRA is right when prohibiting use of unions and bit fields. A changed compiler switch or a new compiler / target platform / tool chain and much more might break this code. For example, the alignment of the ``for_rpc`` might change from tool chain to tool chain. Instead of composing the header like this, it might be a better idea to do it with a serialization function. See http://stackoverflow.com/questions/1044654/bitfield-manipulation-in-c for more info. Further idea: Generate code from ASN.1. – BitTickler May 05 '16 at 08:55
  • In the first example, the size of the inner struct is at least 5 bytes. If you define members that take 5 bytes, then they cannot occupy less than 5 bytes. – 2501 May 05 '16 at 09:43
  • @2501 the total number of bits was equal to 4 bytes (even). – Pawel Veselov May 05 '16 at 09:45
  • @PawelVeselov Union is not a bit-field thus the remaining bits of `for_rpc` cannot be used for the bit-field inside the union. – 2501 May 05 '16 at 09:50

1 Answers1

2

Form the union at the byte level:

typedef struct someip_header { 
    union { 
        uint32_t message_id;
        struct {
            uint16_t service_id; 
            union {
                struct {
                    uint8_t for_rpc : 1; 
                    uint16_t method_id : 15;
                };
                struct {
                    uint8_t for_rpc_2 : 1; 
                    uint16_t event_id : 15;
                };
            };
        };
    };
} someip_header_t;
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358