关于.net:奇怪,C#应用程序内没有错误

strange no error within C# application

本问题已经有最佳答案,请猛点这里访问。

我有一个C#应用程序,其中有以下代码:

1
2
3
4
5
6
7
 public static void Main()
        {
            int i = 2147483647;
            int j = i+1;
            Console.WriteLine(j);
            Console.ReadKey();
        }

结果是:-2147483648

我知道每个整数都必须为< 2147483648。 所以

  • 为什么我没有编译或运行时错误? 就像这个例子

img

  • 出现负号的原因是什么?

谢谢


编译器默认为未经检查的算法;得益于二进制补码存储,您只是溢出和循环。

这在运行时失败:

1
2
3
4
5
6
7
public static void Main()
{
    int i = 2147483647;
    int j = checked((int)(i + 1)); // <==== note"checked"
    Console.WriteLine(j);
    Console.ReadKey();
}

也可以将其作为编译器开关全局启用。


如Christos所说,负号来自整数溢出。 net出现错误的原因是因为编译器不会评估表达式是否存在溢出值。

1
2
3
 0111 1111 1111 1111 1111 1111 1111 1111 2^31-1
+0000 0000 0000 0000 0000 0000 0000 0001 1
=1000 0000 0000 0000 0000 0000 0000 0000 -2^31

其原因是最左边的位是符号位,它确定int是正还是负。 0为正,1为负。如果将一个加到最大可能的数字上,则本质上会更改符号位并获得最小的可表示数字。原因是整数使用二进制补码存储

要检查该值是否溢出,请执行以下操作:

1
int j = checked(i + 1);


Why I don't have a compilation or runtime error?

因为编译器可以确定您已为变量分配了大于int.MaxValue的值。由于它是硬编码的。但是对于i+1,编译器无法执行代码来确定此计算的结果将大于int.MaxValue

What is the reason of the negative sign?

这是因为整数溢出。

参见:选中(C#参考)

By default, an expression that contains only constant values causes
a compiler error if the expression produces a value that is outside
the range of the destination type. If the expression contains one or
more non-constant values, the compiler does not detect the overflow.


What is the reason of the negative sign?

您有一个负号,因为您已经超过了最大整数值,而下一个整数是可以表示的最小整数。

Why I don't have a compilation or runtime error?

您没有编译错误,因为这不是错误。另外,这也不是运行时错误。您只需在运行时将一个添加到i。由于i的值是可以存储在类型int的变量中的最大整数值,并且由于整数在编程中的循环性质,您将获得可以存储在类型的变量中的最低整数int

(类型为int的变量可以存储32位整数)。

此外,默认情况下,您在C#整数运算中不会在溢出时引发异常。您可以从项目设置或使用checked语句更改此设置,因为此处已指出。