我刚刚编写了以下函数来确定计算机体系结构的字节序(尽管是为基于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
会不会有错误的结果?如果是,为什么?
答案 0 :(得分:4)
要回答您的直接问题,如果 unsigned
也可以使用char
和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”)。另外,我个人认为,这样的代码浪费了程序空间,如果您确实需要字节序信息,则最好让您的构建系统为目标确定它,然后#define
(例如,在{{ 1}}文件。
答案 1 :(得分:1)
我只是想知道如果我使用,是否会有错误的结果 这里是
unsigned int
和char
而不是uint32_t
和uint8_t
?如果 是的,为什么?
是的,可能。
提到的类型(unsigned int
和char
)是实现定义的。它可能取决于编译器,计算机,编译器选项等。如果您查看stdint.h中声明的类型。这是standard library的一部分,因此(尽管在技术上无法保证)它有望在所有地方都可用。此处声明的类型包括int8_t
,uint8_t
,int16_t
,uint16_t
,int32_t
,uint32_t
,int64_t
和{ {1}}。
答案 2 :(得分:0)
您可以简单地return ntohs(12345) != 12345
。