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

时间:2019-02-20 19:34:34

标签: c runtime endianness c99 misra

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

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

MISRA不允许在不同类型的指针之间进行转换,因此仅允许将uint32_t*强制转换为uint8_t*并取消引用以查看uint8_t拥有什么值是不允许的。使用union也是不可能的(MISRA不允许union s)。

我还尝试使用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检查器,请将您的想法发送给我,我会告诉您检查器说的是什么

2 个答案:

答案 0 :(得分: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为了将多个不相关的事物存储在同一存储区中,例如创建 variant 和其他此类废话。但是,可以考虑将填充/对齐和尾味考虑在内的受控类型的修剪,可以与MISRA一起使用。也就是说,如果您不喜欢此咨询规则。就我个人而言,我在MISRA实施中始终会忽略它。

答案 1 :(得分:0)

在MISRA上下文中,我想此标头和该功能可能不可用,但是:

#include <arpa/inet.h>

static endi get_endianness(void)
{
    return htons(0x0001u) == 0x0001u ? endi_big : endi_little;
}