【发布时间】:2016-05-05 08:48:09
【问题描述】:
这是我想要的结构:
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;
(原因是如果for_rpc为1,则后15位表示事件ID,否则表示方法ID)
但是这个结构的大小是 5 个字节(打包),我猜是因为编译器不会让 union 不对齐。如果我只用uint16_t val : 15 替换内部联合,则大小会按预期恢复到 4 个字节:
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;
只是想知道,有没有办法打包这个?这真的只是化妆品,但仍然......
【问题讨论】:
-
虽然不是我最喜欢的东西,但 MISRA 在禁止使用联合和位字段时是正确的。更改的编译器开关或新的编译器/目标平台/工具链等可能会破坏此代码。例如,
for_rpc的对齐方式可能会因工具链而异。与其像这样编写标头,不如使用序列化函数来完成它可能是一个更好的主意。有关更多信息,请参阅stackoverflow.com/questions/1044654/bitfield-manipulation-in-c。进一步的想法:从 ASN.1 生成代码。 -
在第一个示例中,内部结构的大小至少为 5 个字节。如果定义的成员占用 5 个字节,那么它们占用的字节数不能少于 5 个。
-
@2501 总位数等于 4 个字节(偶数)。
-
@PawelVeselov Union 不是位域,因此
for_rpc的剩余位不能用于联合内的位域。
标签: c