以正确的方式确定 C 语言中机器体系结构的字节序



我刚刚编写了以下函数来确定机器架构的字节序(虽然是为基于 ARM Cortex-M7 架构的 MCU 编写的,但希望功能使代码可移植

):
uint8_t is_little_endian()
{
static const union test {
uint32_t num;
uint8_t  bytes[sizeof(uint32_t)];
} p = {.num =  1U };              
return (p.bytes[0] == 1U); 
}

我只是想知道如果我在这里使用unsigned intchar而不是在上面的代码中uint32_tuint8_t,是否会有任何错误的结果?如果是,为什么?

为了回答您的直接问题,如果CHAR_BIT < 16unsignedchar也会正常工作。这是因为 C 标准要求unsigned至少具有 16 个值位,并且每种类型的存储大小必须是char(字节)的倍数。因此,只要您的char少于 16 位,unsigned必须至少包含 2 个字节,并且字节序检查将以这种方式工作。

使用char实际上有一个好处,即允许它为任何其他类型添加别名。所以我建议这样的东西:

#include <limits.h>
#if CHAR_BIT > 15
#error exotic platform
#endif
int is_little_endian(void)
{
unsigned x = 1U;
unsigned char *r = (unsigned char *)&x;
return !!*r;
}

我在这里使用unsigned char只是为了确定。

请注意,这假设没有异国情调的字节顺序(如"中端序")。另外,我个人认为这样的代码在程序中浪费空间,如果你真的需要字节序信息,最好让你的构建系统为你的目标确定它,然后#define它(例如在config.h文件中)。

我只是想知道如果我使用unsigned intchar在这里而不是uint32_tuint8_t?如果 是啊,为什么?

是的,可能会。

提到的类型(unsigned intchar)是实现定义的。它可能取决于编译器、机器、编译器选项等。如果您查看 stdint.h 中声明的类型。这是标准库的一部分,因此预计(尽管技术上不能保证)在任何地方都可用。这里声明的类型包括int8_tuint8_tint16_tuint16_tint32_tuint32_tint64_tuint64_t

你可以简单地return ntohs(12345) != 12345.

最新更新