大字节序系统上的地址运算符

时间:2018-12-09 20:42:51

标签: c endianness

许多人都知道以下示例,以了解系统是小端还是大端:

#include <stdio.h> 
int main()  
{ 
   unsigned int i = 1; 
   char *c = (char*)&i; 
   if (*c)     
       printf("Little endian"); 
   else
       printf("Big endian"); 
   getchar(); 
   return 0; 
} 

但是,我想知道以下代码是否仍然有效并且可以正常工作:

#include <stdio.h>
int main()
{
   unsigned int i = 1;
   char *c = &i;
   if (*c)
       printf("Little endian");
   else
       printf("Big endian");
   getchar();
   return 0;
}

这基本上是关于在大字节序系统上如何解释地址运算符&的问题。

假设您不执行上述类型转换,并且还假设一个大字节序系统将向您返回最高位地址(基本上是int的起始位置),那么尽管您已经执行了以下操作,但这段代码仍将显示“ Little endian”真正处理大型字节序系统。

任何对此的评论将非常有帮助。预先谢谢你:D。

2 个答案:

答案 0 :(得分:3)

赋值char *c = &i;违反了C 2018 6.5.16.1 1中的约束。该段显示“以下内容之一将成立”,并且选项列表中最接近的匹配项是:

  • 左操作数具有原子,合格或不合格的指针类型,并且(考虑到左操作数在左值转换后将具有的类型),两个操作数都是指向兼容类型的合格或不合格版本的指针,并且由左侧具有右侧所指类型的所有限定词;

char *int *不兼容,因此分配没有约束。

也就是说,如果编译器确实接受了该语句(因为C标准允许扩展),并且可以将右侧的指针转换为左侧的类型(如应分配的那样),则结果应为指针不管字节序如何,都将保留到对象的最低寻址字节。对于按照C 2018 6.3.2.3 7进行的指针转换,这是正常的:

  

…当将对象的指针转换为字符类型的指针时,结果指向该对象的最低寻址字节。

答案 1 :(得分:-1)

第二个示例将向您提供一个编译器警告,如果不进行强制转换,则该分配无效。 如果忽略该警告,则尝试尝试未定义的行为时,您可能会始终获得相同的结果。