Shifting an integral number by 0 is equivalent to doing nothing but makes the code confusing for maintainers.
If the first operand is an int or uint (32-bit quantity), the shift count is given by the low-order five bits of the
second operand. That is, the actual shift count is 0 to 31 bits.
Note that integral number with a less than 32-bit quantity (e.g. short, ushort…) are implicitly converted to
int before the shifting operation and so the rule for int/uint applies.
If the first operand is a long or ulong (64-bit quantity), the shift count is given by the low-order six bits of the
second operand. That is, the actual shift count is 0 to 63 bits.
public void Main()
{
short s = 1;
short shortShift1 = (short)(s << 0); // Noncompliant
short shortShift1 = (short)(s << 16); // Compliant as short will be cast to int (16 is between 0 and 31)
short shortShift3 = (short)(s << 32); // Noncompliant, this is equivalent to shifting by 1
int i = 1;
int intShift1 = i << 0; // Noncompliant
int intShift2 = i << 32; // Noncompliant, this is equivalent to shifting by 1
long lg = 1;
long longShift1 = lg << 0; // Noncompliant
long longShift2 = lg << 64; // Noncompliant, this is equivalent to shifting by 1
}
public void Main()
{
short s = 1;
short shortShift1 = s;
short shortShift1 = (short)(s << 16);
short shortShift3 = (short)(s << 1);
int i = 1;
var intShift1 = i;
var intShift2 = i << 1;
long lg = 1;
var longShift1 = lg;
var longShift2 = lg << 1;
}
This rule doesn’t raise an issue when the shift by zero is obviously for cosmetic reasons:
bytes[loc+0] = (byte)(value >> 8); bytes[loc+1] = (byte)(value >> 0);