开发者

Size of two structs are the same although one of them has a struct instance in them

开发者 https://www.devze.com 2023-01-11 01:03 出处:网络
typedef struct BaseMessage { int u32DeviceID : 32; int u32CoreID : 32; unsigned int u16Class : 16; unsigned int u8OpCode : 8;
typedef struct BaseMessage
{
    int u32DeviceID : 32;
    int u32CoreID : 32;
    unsigned int u16Class : 16;
    unsigned int u8OpCode : 8;
    unsigned int u16CRC : 16;
} BaseMessage;

typedef struct MessageWithParameters
{
        BaseMessage base;
        int u8Param1 : 8;
        in开发者_JAVA百科t u8Param2 : 8;
} MessageWithParameters;

typedef struct FullMessage
{
        int u32DeviceID : 32;
        int u32CoreID : 32;
        unsigned int u16Class : 16;
        unsigned int u8OpCode : 8;
        unsigned int u16CRC : 16;
        int u8Param1 : 8;
        int u8Param2 : 8;
} FullMessage;

int main()
{
        printf("%d", sizeof(MessageWithParameters));
        printf("%d", sizeof(FullMessage));
}

In MessageWithParameters doesn't the BaseMessage take some size by itself?

Even if it's on the stack?

I am guessing that the compiler turns MessageWithParameters to something that looks like FullMessage.

Am I correct?


You have some padding issue, I would guess. The base has 24-bits "left over", into which the 16-bits added in the parameter struct could fit. Why are you using bitfields? They are universally reviled as A Bad Idea.


As the others said you encounter padding of your structures. Nothing in the C language itself may effectively prevent this. Your compiler might have some extension to pack things, e.g gcc implements this as attribute. But to get things really packed, then, you'd need to reorder your fields in ascending or descending order, such that the alignement gaps get as small as possible.

Also, using bit fields for such structures is generally a bad idea. If you have them use the C99 fixed size integer types like in the following:

typedef struct BaseMessage
{
    int32_t u32DeviceID;
    int32_t u32CoreID;
    uint16_t u16Class;
    uint16_t u16CRC;
    uint8_t u8OpCode;
} BaseMessage;

In this case if your compiler alignes on 16 bits (rare these days) you could get away with just a waste of 8 other additional bits for BaseMessage.


I am guessing that the compiler turns MessageWithParameters to something that looks like FullMessage.
Am I correct?

Nobody can say that. Compiler is free to decide. The standard guarantees members order and no padding before the very first member (including derived members).

0

精彩评论

暂无评论...
验证码 换一张
取 消