用正确的方法确定C语言中机器结构的持久性

用正确的方法确定C语言中机器结构的持久性,c,endianness,C,Endianness,我刚刚编写了以下函数来确定机器体系结构的持久性(不过是为基于ARM Cortex-M7体系结构的MCU编写的,但需要使代码可移植的功能): 我只是想知道如果我在这里使用unsigned int和char而不是在上面的代码中使用uint32\u t和uint8\u t,是否会有任何错误的结果?如果是,原因是什么?您只需返回ntohs(12345)!=12345 要回答您的直接问题,无符号和字符如果字符位15 #误差平台 #恩迪夫 int是_little_endian(void) { 无符号x=1U

我刚刚编写了以下函数来确定机器体系结构的持久性(不过是为基于ARM Cortex-M7体系结构的MCU编写的,但需要使代码可移植的功能):


我只是想知道如果我在这里使用
unsigned int
char
而不是在上面的代码中使用
uint32\u t
uint8\u t
,是否会有任何错误的结果?如果是,原因是什么?

您只需
返回ntohs(12345)!=12345

要回答您的直接问题,
无符号
字符
如果
字符位<16
也同样有效。这是因为C标准要求
无符号
至少有16个值位,并且每种类型的存储大小必须是
字符
的倍数(一个字节)。因此,只要
char
少于16位,一个
无符号的
必须至少包含2个字节,并且endianness检查将以这种方式工作

使用
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;
}
#包括
#如果字符位>15
#误差平台
#恩迪夫
int是_little_endian(void)
{
无符号x=1U;
无符号字符*r=(无符号字符*)&x;
返回!!*r;
}
我在这里使用了
无符号字符
,只是为了确定

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

我只是想知道如果我使用
unsigned int
char
而不是
uint32\u t
uint8\u t
?如果 是的,为什么

是的,可能会


提到的类型(
unsigned int
char
)是实现定义的。它可能取决于编译器、机器、编译器选项等。如果查看中声明的类型。这是的一部分,所以它预计(尽管技术上没有保证)在任何地方都可以使用。这里声明的类型包括
int8\u t
uint8\u t
int16\u t
uint16\u t
int32\u t
uint32\u t
int64\u t
,以及
uint64\u t
,类型signess在这种情况下并不重要,顺便说一句,是什么阻止了你的检查。我只是想知道,如果在所有未签名的int和char将导致任何错误的结果!如果您只是追求可移植性,您会使用像
ntohs
htons
这样的函数吗?不要忘记mixed/middle-endian;)
sizeof(unsigned int)
=>
sizeof(uint32\u t)
?如果可以的话,稍微解释一下就更好了,你不觉得还需要解释一下它的逻辑吗?中端、小端、大端???@snr这不是严格必要的,它将每个非零值“规范化”为
1
。除了
0
,哼哼,C中的每个值都是
1
?我的意思是为什么不仅仅是
*r
?这个函数应该返回一个truthy或false值。任何不是
0
的东西在C中都是真实的,但是true的规范值是
1
。现在,我想我不能确定
char
中的值位的排列方式与
int
中的排列方式相同,因此读取
*r
可以在小型endian机器上给出任何非零值。直接返回这个就可以了,我只是觉得将返回值限制在
0
1
更好;)哼,这是微妙的细微差别。非常感谢你!我希望6天过得很快。我想在这里再见到你。你对我们来说是个有价值的人。我从你身上收获太多了。再见,先生,索内兰,这里。。。虽然使用
无符号
字符
可能出错是正确的,但出现这种情况的可能性非常小;)e、 g.在实际提供
uint8\u t
类型的平台上,它不会出错(因为这要求
char
也有8位)。是的,你的说法让它更清楚。C标准保证字符也是8位的。不,它不是(否则使用
char
unsigned
永远不会出错)。你的答案是正确的。我想说的是,不太可能找到一个
char
的位超过8位的平台——在这样的平台上,
uint8\t
类型不可能存在。
#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;
}