【发布时间】:2019-01-17 13:29:06
【问题描述】:
假设我有一个 typedef,其位字段如下。
typedef struct VIN_oCAN01_3abd61be
{
uint64_t var1:24;
uint64_t var2:4;
uint64_t var3:4
}__attribute__((packed))Message;
我收到uint8_t 缓冲区如下。
uint8_t buffer[4] = {0x1,0x2,0x3,0x14};
目前在我的生产计划中,我的团队建议采用以下方法。
Message *ptrMsg = (Message *)buffer;
即把uint8_t缓冲区赋值给Message类型指针。
我曾建议建议的方法不遵循严格别名规则,而是我们应该按照以下方式进行。
Message msg;
memcpy(&msg,buffer, sizeof(msg));
请注意,没有将缓冲区复制到结构的选项 手动(逐个成员)因为结构非常大。
我的理解正确吗?如果可以,请提供标准文档,我可以用来证明我的观点。
【问题讨论】:
-
除了严格的别名冲突问题之外,还要注意印度性。使用 memcpy 从 char[] 填充 uint 会使您的代码完全不可移植。
-
@AlainMerigot 很好!,我们在
memcpy或指针分配之前处理字节序,只是我没有在这里显示。 -
我认为 严格别名 是编译器的事情,通常它有一个标志,如果它可能会或可能不会为不同的优化级别假设严格别名。
-
@user694733 我定义了位字段。
-
您的位域加起来为 32 位,在
uint64_t中。您不知道这些位域实际上在那些 64 位中的 where 位置。每6.7.2.1p11:“是否将不适合的位域放入下一个单元或与相邻单元重叠是实现定义的。一个单元内的位域分配顺序(高-order to low-order or low-order to high-order)是实现定义。可寻址存储单元的对齐方式是未指定。"位域对于可移植性和可维护性来说只是个坏消息。
标签: c