(首先请注意,我知道在运行时确定字节序不是理想的解决方案,并且有更好的主意。请不要提出来)
我需要在运行时检查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检查器,请将您的想法发送给我,我会告诉您检查器说的是什么
答案 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;
}