1

I just found that this:

ushort i = 4;
i = i + 4;

gives a compiler error:

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

I have to fix it thus:

ushort i = 4;
i = (ushort)(i + 4);

What is the reason behind this? Shouldn't it be obvious and easy to use all data types?

Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195

6 Answers6

6

The literal 4 is an int, so i + 4 is int addition, with i being promoted to an int. The result of this addition is also int, so you cannot assign it to a ushort without the cast, since C# does not allow implicit conversions to numeric types of smaller magnitude.

Lee
  • 142,018
  • 20
  • 234
  • 287
  • Isn't there a potential for data loss for `int`s as well? Why are `Int32`s not promoted to `Int64`s ? – Bart Friederichs Mar 29 '13 at 15:30
  • Because in the old days when these decisions were made int32 was the default int value used in, well, new and shiny 32-bits processors. Int64 is relatively new and only natively supported on 64-bit architecture. – Davio Mar 29 '13 at 15:33
  • @BartFriederichs - Well it's not really about data loss, it's just that `ushort` is a smaller type than `int` so the conversion has to be made explicit, I've edited the answer to try make it clearer. – Lee Mar 29 '13 at 15:37
  • Actually any two shorts added will yield an int. It does not matter if you use a literal or not. adback03 linked to a thread explaining it. – Guvante Mar 29 '13 at 15:40
3

The reason is because a ushort + ushort actually returns an int. Check out this thread for more detail as to why this is the case.

Community
  • 1
  • 1
Andrew Backes
  • 1,884
  • 4
  • 21
  • 37
  • Thanks for the thread, the remark "because the standard says so" clears it for me, because you could say the same thing about int+int being a long. – Bart Friederichs Mar 29 '13 at 15:34
0

its because compiler treats 4 as integer. The conversion from higher to lower data type needs explicit casting.

Parimal Raj
  • 20,189
  • 9
  • 73
  • 110
0

As per the C# language standard, specifically §2.4.4.2 on integer literals:

The type of an integer literal is determined as follows:

If the literal has no suffix, it has the first of these types in which its value can be represented: int, uint, long, ulong. If the literal is suffixed by U or u, it has the first of these types in which its value can be represented: uint, ulong. If the literal is suffixed by L or l, it has the first of these types in which its value can be represented: long, ulong. If the literal is suffixed by UL, Ul, uL, ul, LU, Lu, lU, or lu, it is of type ulong.

So your number is being treated like an int, that is why.

MeTitus
  • 3,390
  • 2
  • 25
  • 49
0

The +-operatior for integer types is defined only between pairs of int, uint, long, and ulong. To calculate i+4 first i has to be converted from ushort through an implicit numeric conversion into int, and the result is of the same type - also int So the type of i+4 is actually int. Since there is no implicit conversion that would allow assigning an int to a variable defined as ushort the compiler gives you an error for i = i + 4.

Note that you still can use the below because += involves an implicit cast:

i += 4;
Joni
  • 108,737
  • 14
  • 143
  • 193
0

I think the main thing to take away from the comments is that int32 was just the 'default' type to be used by the common architecture back in the day. I don't know about native support for smaller integer types by current processors, but I wouldn't be surprised if everything is still converted to int32 by the compiler under water even if it is a ushort.

So (u)short is more like a validation constraint for the programmer than a memory-saver. Even if it is a memory saver, I wouldn't be surprised if more CPU cycles are needed to convert back and to ushorts.

Davio
  • 4,609
  • 2
  • 31
  • 58
  • I am using it as a validation constraint using the `checked` keyword. – Bart Friederichs Mar 29 '13 at 15:39
  • Well of course that's fine. My point is that you shouldn't use it specifically if you want to save memory or CPU cycles, that's missing the point. There's nothing wrong with the reasons you're using it for. If you are programming an API or something similar, just use int, it's what developers expect. – Davio Mar 29 '13 at 15:44