MISRA C:2012 11.3 违规将 (float *) 转换为 (uint32_t *)

问题描述 投票:0回答:1

我有来自串行消息编码器的以下代码:

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。

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

两种数据类型应该具有相同的大小,因此对齐在这里不应该成为问题?

c pointers misra
1个回答
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
 使用相同的字节序,尽管我不知道它们可能有所不同的任何实现。

© www.soinside.com 2019 - 2024. All rights reserved.