Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bug in compiler or misunderstanding? Or operator on shorts [duplicate]

I have a line of code that is giving me an warning message (CS0675) in VS2015, but not in 2013.

shortValue |= (short)anEnum;

Warning CS0675 Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first. The compiler implicitly widened and sign-extended a variable, and then used the resulting value in a bitwise OR operation. This can result in unexpected behavior.

Obviously what is happening is the enum and the short are being extended to an int, the or operator applied, and then the result assigned the result to the short.

If I change the code to shortValue = shortValue | (short)anEnum; I get a compiler error CS0266. But the bitwise OR should be valid for shorts (in both cases I believe). If I hover the mouse over the | it shows as an int operator, am I missing something or should I report this as a bug?

PS: I know I can eliminate the warning/error by using = instead of |= and casting the result to a short.

like image 339
jmoreno Avatar asked Oct 07 '15 19:10

jmoreno


1 Answers

If you look at the C# specifications (specifically in "Integer logical operators") you'll see that there's only a definition for int, uint, long, ulong for the logical OR operator:

int operator |(int x, int y);
uint operator |(uint x, uint y);
long operator |(long x, long y);
ulong operator |(ulong x, ulong y);

Also, in Bit twiddling: What does warning CS0675 mean? Eric Lippert states that:

"There are bitwise-or operators defined on int, uint, long and ulong"

The operator IS valid for short, but only in the sense that the short value can be extended to int. The return value of that operator however, is (at least) an int.

So, technically speaking, according to the specs, this doesn't seem to be a bug as using |= does extend the signed value to int, which gives a warning and the regular | results in an int that needs to be cast down to be assigned to a short.

However, since the compiler can in fact know that both operands are originally shorts, both get extended to int and the result will eventually be stored back into a short it doesn't really matter that the operands are extended. The extension will be lost by the cast from int to short.

So, either the VS2013 compiler was smarter with its warnings than the VS2015 one or the VS2015 fixes a bug and warns where VS2013 failed to. Only the people behind the compiler can answer that but I assume it's indeed a bug (EDIT: and it is).

like image 83
i3arnon Avatar answered Sep 19 '22 06:09

i3arnon