问题
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);
回答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.
回答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
.
回答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?
来源:https://stackoverflow.com/questions/7328052/c-sharp-bitwise-or-operator-used-on-a-sign-extended-operand-consider-casting-to