Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does ?: cause a conversion error while if-else does not? [duplicate]

Making some changes in the code I use the next line:

uint a = b == c ? 0 : 1;

Visual Studio shows me this error:

Cannot implicitly convert type 'int' to 'uint'. An explicit conversion exists (are you missing a cast?)

But if I use the code:

uint a; 

if (b == c) 
    a = 0; 
else 
    a = 1;

It works correctly without any error or warning. Why?

like image 684
Ruben Aguilar Avatar asked Mar 09 '17 08:03

Ruben Aguilar


3 Answers

Why can't I use uint a = b == c ? 0 : 1;?

The type of the expression b == c ? 0 : 1 is int. As shown in this table, there is no implicit conversion from int to uint, so this is not allowed.

Why can I use a = 0?

Because there is special treatment of numeric types when the value is a constant expression.

From section 6.1.9 of the C# specification:

  • A constant expression of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type.

  • A constant expression of type long can be converted to type ulong, provided the value of the constant expression is not negative.

As indicated in the first bullet a = 0 and a = 1 are both allowed because 0 and 1 are constant expressions and are valid uint values. Basically what this boils down to is that the compiler can easily determine at compile time that these conversions are valid, so it allows them.

Incidentally, if the b == c part of your first example were changed to a constant expression (e.g. true), then the whole conditional operator expression would be a constant expression and the code would compile.

like image 152
JLRishe Avatar answered Oct 26 '22 23:10

JLRishe


If b==c were a constant expression then the whole conditional operator would be considered a constant expression and so, then, the rule allowing constant expressions of type int to be converted to other int types would apply and it would compile.

Obviously, b==c is not a constant expression and so the result of the conditional operator cannot be known until runtime and so the exemption that allows an implicit conversion of ints to uint (for constant expressions) does not apply.

In your if/else variant, both of the actual assignments are constant expressions.

like image 26
Damien_The_Unbeliever Avatar answered Oct 26 '22 23:10

Damien_The_Unbeliever


You should use literals to make your code work correctly like this:

uint a = b == c ? 0U : 1U;
like image 10
teo van kot Avatar answered Oct 26 '22 22:10

teo van kot