我刚刚编写了以下函数来确定机器架构的字节序(虽然是为基于 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 int
和char
而不是在上面的代码中uint32_t
和uint8_t
,是否会有任何错误的结果?如果是,为什么?
为了回答您的直接问题,如果CHAR_BIT < 16
,unsigned
和char
也会正常工作。这是因为 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 int
和char
在这里而不是uint32_t
和uint8_t
?如果 是啊,为什么?
是的,可能会。
提到的类型(unsigned int
和char
)是实现定义的。它可能取决于编译器、机器、编译器选项等。如果您查看 stdint.h 中声明的类型。这是标准库的一部分,因此预计(尽管技术上不能保证)在任何地方都可用。这里声明的类型包括int8_t
、uint8_t
、int16_t
、uint16_t
、int32_t
、uint32_t
、int64_t
和uint64_t
。
你可以简单地return ntohs(12345) != 12345
.