从+2147483648转换为-2147483648可预测性

时间:2013-07-19 21:30:19

标签: c

下面描述的行为是否可预测?

我已将这些数字编辑为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;
}

2 个答案:

答案 0 :(得分:1)

您已更改了问题,导致之前的答案无效。

一般来说,程序的行为是不可预测的。

C标准仅保证int可以表示-32767+32767范围内的值(16位)。在此类系统上,常量2147483648的类型为longlong long

即使int为32位,无填充位和二进制补码,2147483648超出int范围,也可能属于longlong 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)); 的整数,则2147483648long long保证足够大。

答案 1 :(得分:0)

根据limits.hsizeof(int) = 4,int的限制为2 147 483 647。所以是的,它是可预测的,因为2 147 483 148&lt; 2 147 483 647。