符合MISRA标准的字节序运行时检测

问题描述 投票:2回答:2

(首先请注意,我知道在运行时确定字节顺序并不是一个理想的解决方案,并且有更好的想法。请不要提出这个问题)

我需要在运行时检查我的CPU的字节顺序。我还必须在保持MISRA兼容的同时这样做。我正在使用C99。

MISRA不允许在不同类型的指针之间进行转换,因此只需将uint32_t*转换为uint8_t*并取消引用以查看uint8_t所持有的值是不允许的。使用unions也是不可能的(MISRA不允许使用unions)。

我也尝试在下面的代码中使用memcmp

static endi get_endianess(void)
{
    uint32_t a = 1U;
    uint8_t b = 1U;

    return memcmp(&a, &b, 1) == 0 ? endi_little : endi_big;
}

但MISRA说,The pointer arguments to the Standard Library function 'memcmp' are not pointers to qualified or unqualified versions of compatible types,意思是我没有通过转换为合法的void*指针并让memcmp做肮脏的工作来超越它。

任何其他聪明的想法将不胜感激。如果您没有MISRA检查员,请将您的想法发给我,我会告诉您我的检查员所说的内容

c runtime endianness c99 misra
2个回答
3
投票

我认为你误解了MISRA-C规则。像这样的代码很好:

 uint16_t u16 = 0xAABBu;
 bool big_endian = *(uint8_t*)&u16 == 0xAAu;

MISRA-C:2012规则11.3有一个例外,允许指针转换指向字符类型(uint8_t可以安全地被视为),但不是相反。规则的目的是防止错位访问和严格别名错误。


此外,MISRA允许union就好了,反对它的规则是建议性的,只是为了迫使人们停下来思考他们如何使用工会。 MISRA不允许union在同一存储区域中存储多个不相关的东西,例如创建变体和其他类似的废话。但是,考虑到填充/对齐和结束的受控类型双关语可以与MISRA一起使用。也就是说,如果你不喜欢这个顾问规则。我个人总是在我的MISRA实现中忽略它。


0
投票

在MISRA上下文中,我认为此标头和此函数可能不可用,但是:

#include <arpa/inet.h>

static endi get_endianness(void)
{
    return htons(0x0001u) == 0x0001u ? endi_big : endi_little;
}
© www.soinside.com 2019 - 2024. All rights reserved.