I’m a Java programmer trying to migrate to C#, and this gotcha has me slightly stumped:
int a = 1;
a = 0x08000000 | a;
a = 0x80000000 | a;
The first line compiles just fine. The second does not. It seems to recognise that there is a constant with a sign bit, and for some reason it decides to cast the result to a long, resulting in the error:
Cannot implicitly convert type ‘long’ to ‘int’.
An explicit conversion exists (are you missing a cast?)
The fix I have so far is:
a = (int)(0x80000000 | a);
Which deals with the cast but still leaves a warning:
Bitwise-or operator used on a sign-extended operand;
consider casting to a smaller unsigned type first
What would be the correct C# way to express this in an error/warning/long-free way?
A numeric integer literal is an
intby default, unless the number is too large to fit in anintand it becomes anuintinstead (and so on forlongandulong).As the value 0x80000000 is too large to fit in an
int, it’s anuintvalue. When you use the|operator on anintand anuintboth are extended tolongas neither can be safely converted to the other.The value can be represented as an int, but then you have to ignore that it becomes a negative value. The compiler won’t do that silently, so you have to instruct it to make the value an
intwithout caring about the overflow:(Note: This only instructs the compiler how to convert the value, so there is no code created for doing the conversion to
int.)