C# Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first

10,522

Solution 1

A quick Web search shows the official documentation for the warning, which comes with an explanation:

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.

The problem is that the expression v75 | 0x862D63D3 is of the form int | uint. This is computed by promoting both sides to long. If you really want sign extension, write (ulong)(long)v75 | 0x862D63D3. If you really want zero-extension, then write (uint)v75 |0x862D63D3.

class Program {
 public static void Main()
 {
  int v75 = int.MinValue;
  System.Console.WriteLine("{0:x}", v75 | 0x862D63D3);
  System.Console.WriteLine("{0:x}", (ulong)(long)v75 | 0x862D63D3);
  System.Console.WriteLine("{0:x}", (uint)v75 | 0x862D63D3);
 }
}

This program prints

ffffffff862d63d3
ffffffff862d63d3
862d63d3

As you can see, the compiler defaults to the first interpretation, which is probably not what you want.

Solution 2

Try casting v75 and other variables being ORed with unsigned hex values to uint:

((uint)v75 | 0x862D63D3)

or declare the variables as uint instead of int.

Solution 3

if you do OR operation for int and long variable, then system cast int to long. Exist two way for it :

namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine($"int.MinValue  = {Convert.ToString(int.MinValue, 2)}");
        Console.WriteLine($"long.MinValue = {Convert.ToString(long.MinValue, 2)}");
        Console.WriteLine();
        long cast1 = int.MinValue;                   // !!!
        long cast2 = unchecked((uint)int.MinValue);  // !!!
        Console.WriteLine($"default cast = {Convert.ToString(cast1, 2)}");
        Console.WriteLine($"custom  cast = {Convert.ToString(cast2, 2)}");
        Console.WriteLine();
        Console.WriteLine($"default long OR int = {Convert.ToString(long.MinValue | int.MinValue, 2)}");
        Console.WriteLine($"custom  long OR int = {Convert.ToString(long.MinValue | unchecked((uint)int.MinValue), 2)}");
}
}

Result:

int.MinValue  = 10000000000000000000000000000000
long.MinValue = 1000000000000000000000000000000000000000000000000000000000000000
default cast = 1111111111111111111111111111111110000000000000000000000000000000
custom  cast = 0000000000000000000000000000000010000000000000000000000000000000
default long OR int = 1111111111111111111111111111111110000000000000000000000000000000
custom  long OR int = 1000000000000000000000000000000010000000000000000000000000000000

How result you want?

Share:
10,522
SSpoke
Author by

SSpoke

Pro programmer from the russia How to be a programmer in steps? 1). Set a goal what you wish to program.. 2). Make your program just work. (don't worry think much how messy your coding is.) 3). Fix all bugs you can find and do tests on each part to make sure no more bugs exist. 4). Finally start from scratch and re-write your program in a clean matter, this will be fast don't worry because you already did this once ;). 4). And always ask StackOverflow for advise on parts you are unsure.

Updated on June 05, 2022

Comments

  • SSpoke
    SSpoke about 1 year

    I know these warnings are probably pointless.. But anyway I could get rid of them?

    I got 7 of these warnings.

    Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first

    This has something to do with the OR operator |

    I highlighted what gives off the warnings.

    int result = (int)ror((uint)(v76 ^ (v75 | 0x862D63D3)), (uint)(BitConverter.ToInt32(v4, 72) ^ 0x22));
    int v11 = (int)rol((uint)(int)((v8 & v10 | ~v10 & 0xEFCDAAC9) + v3[2] - 1126481991), 17);
    int v144 = (int)rol((uint)(int)((v141 & v143 | ~v143 & 0xEFCDAAC9) + v3[2] - 1126481991), 17);
    int v77 = (int)(`BitConverter.ToInt32(v4, 52) | 0x96C35837`);
    BitConverter.GetBytes((int)(v30 & 0x870DEA8A | v29)).CopyTo(v2, 32);
    int temp24 |= (int)(BitConverter.ToInt32(v3, 48) | 0x96B4A1B4);
    int v17 = (int)(BitConverter.ToInt32(v3, 12) | 0x83868A1D);
    
  • Giffyguy
    Giffyguy almost 8 years
    I'm seeing this error with long | int ... no signed/unsigned mismatches that I can find ... the warning goes away when I explicitely cast the int to a long, but then the IDE also informs me that the explicit cast is "redundant" since casting from int to long is supposed to be implicit. I guess it can't make up its mind. :)