Следующий фрагмент оценивается как ноль:
int result = unchecked((int)double.MaxValue);
Принимая во внимание, что если вы сделаете это:
double x = double.MaxValue
int result = (int)x;
В результате (вы даже догадались бы?) int.MinValue
.Уже один этот факт достаточно странный [см. Ниже], но у меня сложилось впечатление, что unchecked
предназначался для того, чтобы заставить компилятор выдавать код, который делает вид, что не знает, что преобразование обязательно завершится неудачей и / или произойдет некоторое переполнение.Другими словами, он должен давать тот же результат, что и когда компилятор ничего не знает о задействованных значениях (при условии, что он скомпилирован с отключенной «проверкой на арифметическое переполнение»)
Итак, что здесь происходит?Неужели мое понимание unchecked
неверно?
Является ли один из результатов "неправильным" в соответствии со стандартом C # /. NET?
edit: объяснен int.MinValue
достаточно просто: cvttsd2si
дает 0x80000000, когда было бы переполнение, но исключение маскируется.Это инструкция, используемая компилятором JIT, как видно в окне разборки.Это не решает ни одной части проблемы.
Согласно ECMA 334 (спецификация C # 2), ключевое слово unchecked
должно всегда обрезаться, и поэтому результат должен быть нулевым в обоихслучаи:
int result1 = unchecked((int)double.MaxValue);
double x = double.MaxValue;
int result2 = unchecked((int)x);
Но это не так, второй дает int.MinValue
.Это все еще пахнет как ошибка компилятора для меня.