return ulong in inline-if [duplicate]
Asked Answered
A

3

6

Is there a reason why I can't use the following code?

ulong test(int a, int b)
{
    return a == b ? 0 : 1;
}

It shows me:

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

The following will work:

ulong test(int a, int b)
{
    return false ? 0 : 1;
}

I know how to solve the problem. I just want to know the reason.

Thanks.

Abstract answered 30/9, 2015 at 16:48 Comment(5)
In the final code block, does it work if you replace false with true? Maybe there's some reason that 1 can be implicitly converted by 0 can't?Player
Already tested, it makes no difference.Bisque
That false ? 0 : 1 is constant expression. That return a == b ? 0 : 1 is not. Constant expression of type int allowed be converted implicitly to ulong if it fit in ulong range.Breve
The reason i think because compiler evaluates the expression so there is no error for second one. it will be compiled as return 1Andersen
"I just want to know the reason." Because that would add complexity to the compiler for no good reason.Pluralism
S
4

Let's take a look at the resulting IL code of the second method:

IL_0000:  nop
IL_0001:  ldc.i4.1
IL_0002:  conv.i8
IL_0003:  stloc.0
IL_0004:  br.s       IL_0006
IL_0006:  ldloc.0
IL_0007:  ret

At IL_0001 the literal 1 is pushed onto the stack (so the expression return false ? 0 : 1; is evaluated at compile-time and embedded into IL as a constant) and at IL_0002 this literal is converted into an Int64.

From MSDN:

A constant-expression (Section 7.15) 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.

Since 1 is in the range of the ulong data type, such conversion will always succeed. The compiler knows that and therefore performs an implicit conversion.

Shatzer answered 30/9, 2015 at 17:4 Comment(0)
P
2

Variables typed as int cannot be implicitly converted to ulong, because an int can represent a negative value, while a ulong cannot. A constant can be implicitly converted, provided that the value of the constant expression is non-negative.

Your second example is a constant expression.

Podite answered 30/9, 2015 at 17:2 Comment(0)
G
0

This will work:

ulong test(int a, int b)
{
    return a == b ? 0UL : 1UL;
}

See, the compiler infers the type from the size of the number, so if you want a specific type, you have to give the suffix. See the Literals section on this MSDN page

Edit: As pointed out to me, this question was not looking for an answer on how to make it work. I believe there is still some value in the MSDN article linked. It provides information that can explain why the failing case is not working, but not as to why the other passes. Interesting problem indeed.

Gauntry answered 30/9, 2015 at 16:51 Comment(2)
The question isn't about how to make it work, it's asking why the second case works when the first does not.Foist
@Foist So it is. Getting to the end of the day and my brain is fried here. Although the literals part still applies right? It explains why it doesn't work, but not why the second case does though.Gauntry

© 2022 - 2024 — McMap. All rights reserved.