2010-04-15 26 views
6

J'ai la fonction suivante pour obtenir un entier à partir d'un octet haut et un bas-octet:Pourquoi l'avertissement FxCop concernant un débordement (CA2233) est-il dans ce code C#?

public static int FromBytes(byte high, byte low) 
{ 
    return high * (byte.MaxValue + 1) + low; 
} 

Lorsque j'analyse l'assemblage avec FxCop, je reçois l'avertissement critique suivant:

CA2233: OperationsShouldNotOverflow
Opérations arithmétiques ne doivent pas être effectuées sans d'abord valider les opérandes pour empêcher le débordement.

Je ne vois pas comment cela pourrait déborder, donc je suppose que FxCop est trop zélé.
Ai-je raté quelque chose? Et quelles mesures pourraient être prises pour corriger ce que j'ai (ou du moins faire disparaître l'avertissement FxCop!)?

+1

Ma mise est sur la partie "byte.MaxValue + 1". – Pwninstein

+4

Votre pari est faux. Son code ne peut pas causer de débordement puisque byte.MaxValue serait TOUJOURS implicitement converti en un int avant que l'étape d'addition ait eu lieu. - Chaque fois qu'une méthode effectue une opération arithmétique et ne valide pas les opérandes au préalable (pour éviter un débordement), vous obtiendrez CA2233. Il existe de nombreux exemples sur la façon de résoudre ce problème sur MSDN à http://msdn.microsoft.com/en-us/library/ms182354.aspx – BrainSlugs83

+0

Lire http://msdn.microsoft.com/en-us/library/ ms182354.aspx – Lijo

Répondre

3

Comme Daniel A. Whitepointed out, vous obtenez le message parce que "(byte.MaxValue + 1)" déborde un octet.

Mais au lieu de la coulée et la multiplication, je voudrais simplement déplacer les bits comme fait dans le code suivant:

public static int FromBytes(byte high, byte low) { 
    return high << 8 | low; 
} 

Comme un effet secondaire, ce code sera probablement de meilleurs résultats. Je n'ai pas vérifié l'IL ou x86 résultant pour voir si le compilateur et/ou le JITter sont assez intelligents pour optimiser l'expression originale.

+4

Encore une fois, byte.MaxValue + 1 ne dépasse pas l'octet. Il reçoit le message parce qu'il ne valide pas ses opérandes. Il s'en va pour votre code puisque votre code n'effectue aucune opération arithmétique, seulement logique binaire. Voir http://msdn.microsoft.com/en-us/library/ms182354.aspx pour plus de détails. – BrainSlugs83

5

Il les fait comme calculs d'octets.

Essayez cette

return (int)high * ((int)byte.MaxValue + 1) + (int)low; 
+0

+1 J'étais juste sur le point de répondre avec la même chose :) – Pwninstein

+0

J'étais sur le point d'écrire ça! Agréable et rapide. :) – Joshua

+1

-1! (Si je pouvais!) C'est incorrect.Vous n'avez pas besoin de convertir byte.MaxValue en entier - lorsque vous ajoutez un entier et un octet - l'octet est automatiquement converti en entier - c'est le point entier d'une conversion implicite. Pour preuve, notez: public static int GetValue() {return Byte.MaxValue + 1} renvoie la valeur 256. Byte + Int = Int. Veuillez également noter que le code que vous avez fourni ne ferait pas disparaître un avertissement CA2233 FxCop. Simplement (i + 1) (où i est un int) provoquera cet avertissement. – BrainSlugs83

3

est ici 2 façons qu'il a finalement arrêté de pleurnicher sur CA2233 pour moi:

public static int FromBytes(byte high, byte low) 
    { 
     int h = high; 
     return h * (byte.MaxValue + 1) + low; 
    } 

    public static int FromBytes2(byte high, byte low) 
    { 
     unchecked 
     { 
      return high * (byte.MaxValue + 1) + low; 
     } 
    } 

Je pense qu'il pourrait être un bug dans la règle.

4

L'addition d'octets et les résultats mult sont des nombres entiers. La valeur maximale ici est 65535 qui ne débordera pas un int. Juste surpresser l'erreur.

byte a = 1; 
byte b = 2; 
object obj = a + b 

obj est de type int

Essayez ceci:

 byte high = 255; 
     byte low = 255; 
     checked 
     { 
      int b = high * (byte.MaxValue + 1) + low; 
     } 

Pas de problème.

ou essayer