以正确的方式确定C中机器体系结构的字节顺序
Determining endianness of machine architecture in C the correct way
我刚刚编写了以下函数来确定机器体系结构的字节顺序(虽然是为基于 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
是否会出现任何错误结果?如果是,为什么?
你可以简单地return ntohs(12345) != 12345
。
为了回答您的直接问题,unsigned
和 char
也可以正常工作 if CHAR_BIT < 16
。这是因为 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
只是为了确定。
请注意,这是假设没有 exotic 字节顺序(如 "middle-endian")。另外,我个人认为这样的代码在程序中是 space 的浪费,如果你真的需要字节顺序信息,最好让你的构建系统为你的目标确定它并且只是 #define
它(例如在 config.h
文件中)。
I was just wanting to know if there will be false results if I use
unsigned int
and char
here instead of uint32_t
and uint8_t
? If
yes, why?
是的,可能。
提到的类型(unsigned int
和 char
)是 实现定义的。它可能取决于编译器、机器、编译器选项等。如果您查看 stdint.h. This is part of the standard library 中声明的类型,那么预计(尽管技术上不能保证)在任何地方都可用。此处声明的类型包括 int8_t
、uint8_t
、int16_t
、uint16_t
、int32_t
、uint32_t
、int64_t
和 uint64_t
.
我刚刚编写了以下函数来确定机器体系结构的字节顺序(虽然是为基于 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
是否会出现任何错误结果?如果是,为什么?
你可以简单地return ntohs(12345) != 12345
。
为了回答您的直接问题,unsigned
和 char
也可以正常工作 if CHAR_BIT < 16
。这是因为 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
只是为了确定。
请注意,这是假设没有 exotic 字节顺序(如 "middle-endian")。另外,我个人认为这样的代码在程序中是 space 的浪费,如果你真的需要字节顺序信息,最好让你的构建系统为你的目标确定它并且只是 #define
它(例如在 config.h
文件中)。
I was just wanting to know if there will be false results if I use
unsigned int
andchar
here instead ofuint32_t
anduint8_t
? If yes, why?
是的,可能。
提到的类型(unsigned int
和 char
)是 实现定义的。它可能取决于编译器、机器、编译器选项等。如果您查看 stdint.h. This is part of the standard library 中声明的类型,那么预计(尽管技术上不能保证)在任何地方都可用。此处声明的类型包括 int8_t
、uint8_t
、int16_t
、uint16_t
、int32_t
、uint32_t
、int64_t
和 uint64_t
.