2011-09-07 7 views
14

Sé que estas advertencias son probablemente inútiles ... ¿Pero de todos modos podría deshacerme de ellas?C# operador bit a bit utilizado en un operando con signo extendido; considere la posibilidad de enviar a un tipo sin signo más pequeño primero

Recibí 7 de estas advertencias.

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

Esto tiene algo que ver con el operador OR |

destaqué lo emite las advertencias.

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); 
+0

Esto puede confundir adicionalmente con una combinación de cortos firmados y no firmados, solo piense en qué tipo se promocionarán sus sub expresiones y siga los consejos en la respuesta aceptada. Ejercicio para el lector: intente y obtenga "uint x = (<< 16) | " para compilar. – yoyo

Respuesta

22

Una búsqueda rápida en la web muestra the official documentation for the warning, que viene con una explicación. El problema es que la expresión v75 | 0x862D63D3 tiene la forma int | uint. Esto se calcula promocionando ambas partes al long. Si realmente desea la extensión de la señal, escriba (ulong)(long)v75 | 0x862D63D3. Si realmente quiere una extensión cero, escriba (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); 
} 
} 

Este programa imprime

ffffffff862d63d3 
ffffffff862d63d3 
862d63d3 

Como se puede ver, el compilador por defecto a la primera interpretación, que probablemente no es lo que desea.

+2

Estoy viendo este error con 'long | int' ... no hay desacuerdos firmados/no firmados que pueda encontrar ... la advertencia desaparece cuando explícitamente echo 'int' a' long', pero luego el IDE también me informa que el lanzamiento explícito es "redundante" desde el lanzamiento de 'int' a' long' se supone que está implícito. Supongo que no puede decidirse. :) – Giffyguy

2

V75 intenta transmitir y otras variables que son un OR con valores hexadecimales sin signo a uint:

((uint)v75 | 0x862D63D3) 

o declarar las variables como uint en lugar de int.

1

si realiza la operación O para la variable int y larga, entonces el sistema emitirá int a largo. Existen dos camino para ello:

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)}"); 
} 
} 

Resultado:

int.MinValue = 10000000000000000000000000000000 
long.MinValue = 1000000000000000000000000000000000000000000000000000000000000000 

default cast = 1111111111111111111111111111111110000000000000000000000000000000 
custom cast = 0000000000000000000000000000000010000000000000000000000000000000 

default long OR int = 1111111111111111111111111111111110000000000000000000000000000000 
custom long OR int = 1000000000000000000000000000000010000000000000000000000000000000 

Como resultado deseado?

Cuestiones relacionadas