Почему добавление двух больших целых чисел, результат которых больше, чем int.MaxValue, не вызывает исключение переполнения?

Если мы используем следующий цикл в программе, цикл никогда не заканчивается в C# 4.0.

for (int i = 1; i <= int.MaxValue; i++)
{
}

Это связано с тем, что добавление 1 к int.MaxValue (2147483647) не приведет к исключению переполнения, а приведет к -2147483648 (принимая во внимание 32-битное целое и дополнение 2).

int i = int.MaxValue;
Console.WriteLine(i + 1);

Кажется, поведение изменилось в последнее время. См. вопрос Арифметическая операция вызвала OverflowException .Что может быть причиной этого изменения?


person renil    schedule 19.08.2011    source источник
comment
Этот цикл должен закончиться, когда i == int.MaxValue.   -  person Oliver Charlesworth    schedule 19.08.2011


Ответы (1)


Исключения переполнения для целочисленных (и других целочисленных типов) выполняются только в checked. контексты.

Итак, это вызовет исключение:

checked
{
 int i = int.MaxValue;
  Console.WriteLine(i + 1);
}

Они не настроены на это по умолчанию, так как они дороже, чем просто переполнение.

Из MSDN:

Ключевое слово checked используется для явного включения проверки переполнения для арифметических операций и преобразований целочисленного типа.

И:

Проверку переполнения можно включить с помощью параметров компилятора, конфигурации среды или использования ключевого слова checked.


Это не недавнее изменение — C# был таким с самого первого дня. В вопросе вы видите код VB.NET, который по умолчанию находится в проверенном контексте.

Таким образом, при сохранении значений по умолчанию переполнение кода в VB.NET вызовет исключение, а идентичный код в C# — нет.

person Oded    schedule 19.08.2011
comment
Это интересно. Я не осознавал, что различия между VB.Net и C# более чем поверхностны. - person 48klocs; 19.08.2011