C 将短路分配给int*失败

C 将短路分配给int*失败,c,pointers,integer,short,C,Pointers,Integer,Short,我知道我可以将一个变量重新分配给一个更大的类型,如果它合适的话。例如: short s = 2; int i = s; long l = i; long long ll = l; 当我尝试使用指针时,它失败了,我不明白为什么。我将整数作为参数传递给期望指针指向long的函数。而且它还没有失败 前几天,我从short改为int,发生了一些奇怪的事情,我希望有人能给我解释一下。这将是复制的最小代码 short s = 2; int* ptr_i = &s; // here ptr_i i

我知道我可以将一个变量重新分配给一个更大的类型,如果它合适的话。例如:

short s = 2;
int i = s;
long l = i;
long long ll = l;
当我尝试使用指针时,它失败了,我不明白为什么。我将整数作为参数传递给期望指针指向long的函数。而且它还没有失败

前几天,我从short改为int,发生了一些奇怪的事情,我希望有人能给我解释一下。这将是复制的最小代码

short s = 2;
int* ptr_i = &s; // here ptr_i  is the pointer to s, ok , but *ptr_i   is definitely not 2
当我尝试使用指针时,它失败了,我不明白为什么

C中类型系统的一个主要目的是减少编程错误。默认转换可能被禁止或诊断,因为它是错误的征兆,而不是因为无法转换值

int*ptr_i=&s
&s
的地址,通常为16位整数。如果
ptr\u i
被设置为指向相同的内存,并且使用了
*ptr\u i
,它将尝试引用该地址处的
int
,通常是32位整数。这通常是一个错误;从一个有16位整数的地方加载一个32位整数,我们不知道它后面是什么,这通常不是一个理想的操作。C标准没有定义尝试此操作时的行为

事实上,这可能会导致多方面的问题:

  • 如上所述,使用
    *ptr_i
    当我们只知道存在
    时,可能会产生不期望的结果
  • short
    对象可能具有不适合
    int
    的对齐方式,这可能会导致指针转换或使用转换后的指针出现问题
  • C标准没有定义将
    short*
    转换为
    int*
    的结果,除非正确对齐
    int
    ,结果可以转换回
    short*
    ,以产生与原始指针相等的值
  • 即使
    short
    int
    的宽度相同,比如说32位,并且对齐良好,C标准也有关于别名的规则,允许编译器假设
    int*
    从不访问定义为
    short
    的对象。因此,程序的优化可能会以意想不到的方式对其进行转换
我将整数作为参数传递给期望指针指向long的函数


C允许将整数默认转换为宽度相同或更宽的整数,因为这通常不是错误。

了解为什么可以将int或short或其他类型的参数传递给具有另一整型参数的函数。但是整数不是指针,它们有不同的规则。数据指针的大小都是一样的。目标的大小不同。如果
sizeof(int)!=sizeof(short)
,因为它无法访问正确的目标大小。如果您的编译器警告不兼容的指针类型,您应该将其视为一个bug并修复它。但这意味着
int*
long long int*
也永远不会兼容,但这不会失败。谢谢@Shawn@piptin不,如果
sizeof(int)!=sizeof(long-long-int)
。但由于它们在大多数平台上的大小不同,它们在您的平台上可能不兼容。仅仅因为你没有看到问题并不意味着它不存在。如果将
long-long
作为
int
加载,可能会得到低阶(在小端机器上)或高阶(在大端机器上)。您可能没有注意到差异,但这是未定义的行为。如果存储到更大的大小,则情况会更糟,因为会损坏内存。解决方案是使用
-Wall-Wextra-Werror
编译,然后修复代码中的错误。