我有来自串行消息编码器的以下代码:
uint32_t bits;
*((float *) &bits) = some_external_variable;
pFrame->data[0x2C] = ((uint8_t)(bits >> 0x18) & 0xFFu);
pFrame->data[0x2D] = ((uint8_t)(bits >> 0x10) & 0xFFu);
pFrame->data[0x2E] = ((uint8_t)(bits >> 0x08) & 0xFFu);
pFrame->data[0x2F] = ((uint8_t)(bits >> 0x00) & 0xFFu);
我试图以独立于字节序的方式将
float
值放入字节流中。为此,我(认为我)需要访问字节并将它们单独放入流中。
字节映射本身看起来符合 MISRA-C 标准,但我无法找到任何方法以兼容的方式序列化浮点而不使用
cppcheck
工具触发规则 11.3。
如何以兼容的方式对浮点数进行编码?
两种数据类型应该具有相同的大小,因此对齐在这里不应该成为问题?
将指向一种类型的指针转换为指向不同类型的指针并取消引用(少数特殊情况除外)是未定义的行为。
它定义良好的一种情况是,如果您转换为字符类型,该类型允许您访问变量表示的字节:
unsigned char *bits = (unsigned char *)some_external_variable;
pFrame->data[0x2C] = bits[3];
pFrame->data[0x2D] = bits[2];
pFrame->data[0x2E] = bits[1];
pFrame->data[0x2F] = bits[0];
或者你可以只使用memcpy
:
memcpy(&pFrame->data[0x2C], some_external_variable,
sizeof some_external_variable);
正如您提到的与字节序无关,您可以先从 memcpy
到
uint32_t
,然后像以前一样进行转换:
uint32_t bits;
memcpy(&bits, some_external_variable, sizeof bits);
pFrame->data[0x2C] = ((uint8_t)(bits >> 0x18) & 0xFFu);
pFrame->data[0x2D] = ((uint8_t)(bits >> 0x10) & 0xFFu);
pFrame->data[0x2E] = ((uint8_t)(bits >> 0x08) & 0xFFu);
pFrame->data[0x2F] = ((uint8_t)(bits >> 0x00) & 0xFFu);
这假设 float
和
uint32_t
使用相同的字节序,尽管我不知道它们可能有所不同的任何实现。