两个结构的大小是相同的,尽管其中一个结构中包含结构实例

时间:2010-08-12 08:35:09

标签: c struct sizeof

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

MessageWithParameters BaseMessage中,MessageWithParameters自身的尺寸不是很大吗? 即使它在堆栈上?
我猜测编译器会将FullMessage变为看起来像{{1}}的东西 我是对的吗?

3 个答案:

答案 0 :(得分:2)

我猜你有一些填充问题。基数有24位“剩余”,参数struct中添加的16位可以容纳在其中。你为什么使用位域?他们被普遍谴责为一个坏主意。

答案 1 :(得分:1)

  

我猜测编译器会将MessageWithParameters变为看起来像FullMessage的东西   我是对的吗?

没有人能这么说。编译器可以自由决定。该标准保证成员订单,并且在第一个成员(包括派生成员)之前没有填充。

答案 2 :(得分:1)

正如其他人所说,你会遇到结构的填充物。 C语言本身没有任何东西可以有效地防止这种情况。您的编译器可能对 pack 事物有一些扩展,例如gcc将其实现为attribute。但是为了让事情变得非常紧密,那么你需要按照升序或降序对字段进行重新排序,以使对齐间隙尽可能小。

此外,对这种结构使用位域通常是个坏主意。如果你有它们使用C99固定大小的整数类型,如下所示:

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

在这种情况下,如果您的编译器以16位(这些天很少见)对齐,您只需浪费BaseMessage的其他8位。