zshift zshift - 9 months ago 13
C# Question

How does casting ternary expression solve overflow compilation error

I don't understand how the C# compiler is assigning

works
without a compilation error in the code below. This code compiles and runs correctly, but the second assignment of
worksUnchecked
will not compile if it is not placed in an
unchecked
block.

var min = int.MinValue;
uint works = (uint)(min < 0 ? -min : min);
uint worksUnchecked = unchecked((uint)-int.MinValue);


Why does the compiler allow the assignment from the ternary expression?

Answer Source

This doesn't really have anything to do with the ternary operator per se. Rather, it's because in the context of the ternary operator, you are casting variable values at runtime, while in the context of the uintMin2, you are casting a literal at compile-time.

And the reason this matters is that the default checked/unchecked context is different at compile time than it is at runtime.

From the documentation:

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

Which is another way of saying that, by default, if the compiler can determine that an expression is out-of-range, it will generate an error. If it can't (within the rules of the language specification…that it theoretically could by actually tracing the execution of the code at compile-time would be irrelevant), then it won't.

These defaults can be changed, of course. As you've already seen, you can apply unchecked to force the compiler to ignore errors at compile-time. You can also use the /checked compiler switch to control what happens at compile-time.