2

Possible Duplicate:
Conditional operator cannot cast implicitly?

When writing a statement using the conditional operator, if the either of the expressions are numeric values they are always interpreted as int type. This makes a cast necessary to assign a short variable using this operator.

bool isTrue = true;
int intVal = isTrue ? 1 : 2;
short shortVal = isTrue ? 1 : 2;  // Compile error: Cannot implicitly convert type 'int' to 'short'. 

Shouldn't the compiler be able to know that both values are valid short values just as it would in a typical assignment statement(short shortVal = 1;)?

Community
  • 1
  • 1
heavyd
  • 17,303
  • 5
  • 56
  • 74
  • 6
    This is a duplicate of http://stackoverflow.com/questions/2215745/conditional-operator-cannot-cast-implicitly/2215959#2215959. See my answer there. – Eric Lippert Mar 01 '10 at 14:58

2 Answers2

3

This is because your 1 and 2 are ints. ?: returns the same type as 2nd and 3rd operands in your case.


Edit: At my VS2008 this works:

short x = true ? 1 : 2;

Did I do something wrong?


Edit: Indeed, the difference was that true was a compile-time constant. For non-constant expressions I got the same error message.

Vlad
  • 35,022
  • 6
  • 77
  • 199
  • Yes, but `short shortVal = 1;` does not give me the same compile error. – heavyd Mar 01 '10 at 14:58
  • @heavyd: indeed, see the edit. – Vlad Mar 01 '10 at 14:59
  • @heavyd: Given an example of `short x = 32767;`, the C# page for short says "In the preceding declaration, the integer literal 32767 is implicitly converted from int to short. If the integer literal does not fit into a short storage location, a compilation error will occur." – Powerlord Mar 01 '10 at 15:00
  • @Vlad, yes, I'm assuming the compiler is optimizing out the conditional expression in this case. – heavyd Mar 01 '10 at 15:00
  • 4
    If the condition is a compile time constant true and the consequence is a compile-time constant int, then the whole thing is treated as a constant int. But if the condition is not a compile-time constant then the expression is treated as a non-constant int, no matter what the consequence or alternative expressions are. – Eric Lippert Mar 01 '10 at 15:04
  • @heavyd: a decent compiler should be not allowed to be able to compile or not some code just because of optimization. So I hope your suggestion is wrong. – Vlad Mar 01 '10 at 15:05
  • @Eric: thanks! So the difference is between assigning a constant int and non-constant one? A constant int can be implicitly casted to short, whereas a non-constant cannot? – Vlad Mar 01 '10 at 15:07
  • @Vlad: It has nothing to do with optimization. A constant expression has to be one particular value. We don't say "well, this expression could be the constant 1 or the constant 2, and therefore it is the constant "one or two" and therefore it fits into a short". We could do that, but now consider if the conditional expression was more complex. How much information do you want us to carry around in each constant? "This constant could be one or two or four billion, but it is only four billion if x is true, and it is assigned to a short if x is false, therefore the assignment should be legal..." – Eric Lippert Mar 01 '10 at 18:15
  • @Vlad: A constant int that fits into a smaller integral type is allowed to be implicitly converted to that type, yes. – Eric Lippert Mar 01 '10 at 18:16
  • @Eric: my comment about the optimization was in response to the comment #4. I wonder what is the exact difference between compile time constants and non-constants. Is being a const just reserved to arithmetical expressions without function calls, or deterministic functions are allowed as well? `Math.sin(1) < 50 ? 1 : 2` is definitely a constant `1`, but does compiler go so deeply? – Vlad Mar 01 '10 at 19:26
  • @Vlad: Section 7.18 of the spec carefully defines exactly what a compile-time constant is. – Eric Lippert Mar 01 '10 at 21:14
  • @Eric: I see, thanks. In fact, no functions are allowed. :-( – Vlad Mar 01 '10 at 21:30
  • @Vlad: Indeed. Now, Sin is what we call a "pure" function; its output depends solely upon its inputs and it has no observable side effects, so we could in theory calculate it at compile time. Pure methods are also nice because you can automatically parallelize them and run them on other threads. We're doing some research into how to take advantage of methods that are known at compile time to be pure, but it's a tricky problem and it might be that nothing ever comes of it. – Eric Lippert Mar 01 '10 at 23:15
3

It's not that the conditional operator (AKA ternary operator) always returns ints, it's because your literals are ints.

Unfortunately, C# doesn't appear to have a literal specifier for bytes or shorts (they do for longs, though).

Powerlord
  • 87,612
  • 17
  • 125
  • 175