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

时间秒杀一切 提交于 2019-12-03 22:35:00
Raymond Chen

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.

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.

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?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!