I just discovered that C# will not let you perform bitwise operations on a ulong
and an int
. Every other combination of int
, uint
, long
, and ulong
will work, but that one pairing doesn't.
However, if instead of an int
, I have a const int
, everything is fine.
What's going on here? Why is int & ulong
invalid, but const int & ulong
valid?
Broken:
int mask = 0x1110;
ulong value = 0x1010;
var result = mask & value; // Compilation error: "Operator '&' cannot be applied to operands of type 'int' and 'ulong'"
Working:
const int mask = 0x1110;
ulong value = 0x1010;
var result = mask & value; // Works just fine.
This behavior is not specific to bitwise operations. According to C# Language Specification, it applies to all binary operations requiring numeric promotions.
Section 7.6.3.2 describes binary numeric promotions. I emphasized the section that specifies the behavior that you see:
Binary numeric promotion consists of applying the following rules, in the order they appear here:
- If either operand is of type
decimal
, the other operand is converted to typedecimal
, or a binding-time error occurs if the other operand is of typefloat
ordouble
.- Otherwise, if either operand is of type
double
, the other operand is converted to typedouble
.- Otherwise, if either operand is of type
float
, the other operand is converted to typefloat
.- Otherwise, if either operand is of type
ulong
, the other operand is converted to typeulong
, or a binding-time error occurs if the other operand is of typesbyte
,short
,int
, orlong
.- Otherwise, if either operand is of type
long
, the other operand is converted to typelong
.- Otherwise, if either operand is of type
uint
and the other operand is of typesbyte
,short
, or int, both operands are converted to typelong
.- Otherwise, if either operand is of type
uint
, the other operand is converted to typeuint
.- Otherwise, both operands are converted to type
int
.
The reason the problem does not happen when you use const
is that the compiler is allowed to convert const int
expression to other types, as described in section 7.19:
An implicit constant expression conversion (§6.1.9) permits a constant expression of type
int
to be converted tosbyte
,byte
,short
,ushort
,uint
, orulong
, provided the value of the constant expression is within the range of the destination type.
Since the value of mask
, i.e. 0x1110
, fits within ulong
, the compiler performs the promotion instead of triggering the error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With