All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.plugins.csharp.S2183.html Maven / Gradle / Ivy

There is a newer version: 10.2.0.105762
Show newest version

Why is this an issue?

The shifting operators are used to do an arithmetic shift to the bits of an integral numeric value, either to the left or the right.

var number = 14;         // ...01110 (14)
var left = number << 1;  // ...11100 (28)
var right = number >> 1; // ...00111 (7)

Therefore, shifting an integral number by 0 is equivalent to doing nothing, since the bits do not move any positions to the left or the right.

On the other hand, shifting an integral number by a value greater than their count of bits minus one (n_bits-1) is equivalent to shifting by the value modulo the bit count of the number (value % n_bits).

In the case of int and uint, which take 32 bits in the memory, the shift count is given by the five low-order bits of the second operand, which can represent numbers from 0 to 31. This means that numbers having the same five low-order bits are treated the same by the shift operators.

var one =         0b0_00001;
var thirtyThree = 0b1_00001; // Same five low-order bits, 33 % 32 = 1

var shifted1 = 42 << one;           // Results in 84
var shifted2 = 42 << thirtyThree;   // Results in 84

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 six low-order bits of the second operand. That is, the actual shift count is 0 to 63 bits.

Exceptions

This rule doesn’t raise an issue when the shift by zero is obviously for cosmetic reasons:

  • When the value shifted is a literal.
  • When there is a similar shift at the same position on line before or after. E.g.:
bytes[loc+0] = (byte)(value >> 8);
bytes[loc+1] = (byte)(value >> 0);

How to fix it

Code examples

Noncompliant code example

short s = 1;
short shortShift1 = (short)(s << 0); // Noncompliant: the value does not change
short shortShift2 = (short)(s << 33); // Noncompliant: this is equivalent to shifting by 1

int i = 1;
int intShift = i << 33; // Noncompliant: this is equivalent to shifting by 1

long lg = 1;
long longShift1 = lg << 0; // Noncompliant: the value does not change
long longShift2 = lg << 65; // Noncompliant: this is equivalent to shifting by 1

Compliant solution

short s = 1;
short shortShift1 = s;
short shortShift2 = (short)(s << 1);

int i = 1;
var intShift = i << 1;

long lg = 1;
var longShift1 = lg;
var longShift2 = lg << 1;

Resources

Documentation





© 2015 - 2024 Weber Informatics LLC | Privacy Policy