我有来自一个串口消息编码器的以下代码:

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

我正在try 以一种独立于字符顺序的方式将float值放入字节流.要做到这一点,我(我想我)需要访问字节并将它们单独放到流中.

字节映射本身似乎符合MISRA-C,但我想不出任何方法来以兼容的方式序列化浮点,而不使用cppcheck工具触发规则11.3.

我如何以兼容的方式对浮点数进行编码?

这两种数据类型应该具有相同的大小,所以对齐在这里不应该是问题?

最新情况:

感谢你的回答,特别是对隐藏trap 的澄清.我最终 Select 了这个解决方案:

uint32_t bits;
(void)memcpy(&bits, some_external_variable, sizeof(bits));
pFrame->data[0x2C] |= ((uint8_t)(bits >> 0x00) & 0xFFu);
pFrame->data[0x2D] |= ((uint8_t)(bits >> 0x08) & 0xFFu);
pFrame->data[0x2E] |= ((uint8_t)(bits >> 0x10) & 0xFFu);
pFrame->data[0x2F] |= ((uint8_t)(bits >> 0x18) & 0xFFu);

免责声明:这段代码是我的代码生成器的输出,从该上下文中我预先知道变量的大小匹配.在这里,大范围的移位和口罩看起来像是无法操作的,但在容器未对准的情况下,口罩将发挥作用.

推荐答案

将指向一种类型的指针转换为指向不同类型的指针并取消引用(少数特殊情况除外)是未定义的行为.

is定义良好的一种情况是,如果您强制转换为允许您访问变量表示的字节的字符类型:

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

正如您提到的与字节顺序无关的,您可以先从memcpyuint32_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);

这假设floatuint32_t使用相同的字符顺序,尽管我不知道它们可能有什么不同的实现.

C++相关问答推荐

C sscanf没有捕获第二个参数

自定义malloc实现上奇怪的操作系统依赖行为

segfault在C中使用getline()函数

字符串令牌化xpath表达式

如何跨平台处理UTF-16字符串?

C是否用0填充多维数组的其余部分?

如何在STM8项目中导入STM8S/A标准外设库(ST VisualDeveloper)?

为什么此共享库没有预期的依赖项?

FRIDA-服务器成为端口扫描的目标?

在句子中转换单词的问题

C代码可以在在线编译器上运行,但不能在Leetcode上运行

如何在不使用字符串的情况下在c中编写函数atof().h>;

STM32 FATFS用户手册(Um1721)中的代码正确吗?

问题:C#Define上的初始值设定项元素不是常量

在printf()中用%.*S格式填充长度为0的字符串是否会调用任何UB?如果是,是哪一个?

强制GCC始终加载常量(即只读),即使启用了优化

为什么argc和argv即使在主函数之外也能工作?

当另一个指向 const 的指针观察到数据时,通过指针更改数据是否安全?

传递参数:C 和 C++ 中 array 与 *&array 和 &array[0] 的区别

在 C 中传递参数时出现整数溢出