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