用正确的方法确定C语言中机器结构的持久性
我刚刚编写了以下函数来确定机器体系结构的持久性(不过是为基于ARM Cortex-M7体系结构的MCU编写的,但需要使代码可移植的功能):用正确的方法确定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
我只是想知道如果我在这里使用
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;
}