下面描述的行为是否可预测?
我已将这些数字编辑为2147483648的限制。它似乎仍有效。这是可以预测的吗?
a.out执行
e1r4p22% ./a.out
-2147483648
4
的main.c
#include <stdio.h>
int main()
{
int i = 2147483648;
i = -i;
printf("%d\n", i);
printf("%lu\n", sizeof(int));
return 0;
}
答案 0 :(得分:1)
您已更改了问题,导致之前的答案无效。
一般来说,程序的行为是不可预测的。
C标准仅保证int
可以表示-32767
到+32767
范围内的值(16位)。在此类系统上,常量2147483648
的类型为long
或long long
。
即使int
为32位,无填充位和二进制补码,2147483648
超出int
范围,也可能属于long
或long long
。
此:
int i = 2147483648;
隐式将<{1}}或long
值转换为long long
。结果是实现定义的 - 或者它可以引发实现定义的信号。
在许多系统上,实现定义的结果将是int
。如果是,那么:
-2147483648
试图否定该值,产生的结果超出i = -i;
的范围。与转换不同,溢出算术运算符(如一元int
)对于签名类型具有未定义行为。
该程序很可能会像在您的系统上一样运行,但不是,就C标准而言,它是不可预测的。编译器可以自由地假设你的程序的行为已经很好地定义,并根据这个假设生成代码,所以它实际上可能会以某种意想不到的方式表现出来。
此外:
-
如果 printf("%lu\n", sizeof(int));
(size_t
运算符的结果)在您的系统上为sizeof
,这将正常运行。如果不是,那么再次,您有未定义的行为。 unsigned long
的正确格式为size_t
:
"%zu"
这是在C99中引入的,因此某些实现(特别是Microsoft)可能不支持它。您还可以使用强制转换将参数转换为适当的类型:
printf("%zu\n", sizeof(int));
无论这些代码试图完成什么,几乎可以肯定有更明确的方法。如果您希望能够操作值为printf("%lu\n", (unsigned long)sizeof(int));
的整数,则2147483648
或long long
保证足够大。
答案 1 :(得分:0)
根据limits.h
和sizeof(int) = 4
,int的限制为2 147 483 647。所以是的,它是可预测的,因为2 147 483 148&lt; 2 147 483 647。