代码之家  ›  专栏  ›  技术社区  ›  the_drow

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

  •  0
  • the_drow  · 技术社区  · 15 年前
    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 自己拿一些尺寸?
    即使它在堆栈上?
    带参数的消息 看起来像 FullMessage .

    3 回复  |  直到 15 年前
        1
  •  1
  •   Jens Gustedt    15 年前

    正如其他人所说,你遇到了你的结构填充。C语言本身没有任何东西可以有效地阻止这种情况。您的编译器可能对 包装 事物,例如gcc将其实现为 attribute . 但是要真正打包,您需要按升序或降序对字段进行重新排序,以便对齐间隙尽可能小。

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

    在这种情况下,如果您的编译器在16位上对齐(现在很少),那么您只需浪费8个额外的位就可以了 BaseMessage .

        2
  •  2
  •   anon anon    15 年前

    我猜你有填充问题。基址有24位“剩余”,参数struct中添加的16位可以放入其中。为什么要使用位域?他们被普遍认为是个坏主意。

        3
  •  1
  •   adf88    15 年前

    MessageWithParameters 看起来像 FullMessage .
    我说的对吗?