Partager via


C6291

Avertissement C6291 : opération de bits sur résultat logique : ! bénéficie d'une priorité supérieure à celle de |. Utilisez || ou (!(x | y)) à la place

L'opérateur ! génère un résultat Boolean, et l'opérateur de bits |(OR) accepte deux arguments arithmétiques. L'opérateur ! a également une priorité plus élevée que |.

Par conséquent, l'une des erreurs suivantes a été détectée :

  • L'expression n'est pas mise correctement entre parenthèses :

    Étant donné que le résultat de ! est une valeur Boolean (zéro ou 1), une tentative visant à tester que deux variables ont des bits définis revient à tester que le bit le plus faible est présent sur le côté droit : ((!x) | y) != (!(x | y)) lorsque x == 0 et y == 1.

  • L'opérateur ! est incorrect, et doit être ~ :

    L'opérateur ! obtient un résultat Boolean, mais l'opérateur ~ obtient un résultat arithmétique. Ces opérateurs ne sont jamais interchangeables, même lorsqu'ils utilisent une valeur Boolean (zéro ou 1) : ((!x) | y) != ((~x) | y) lorsque x == 1 et y == 0.

  • L'opérateur binaire | est incorrect et doit être remplacé par || :

    Bien que | puisse parfois être permuté avec ||, il n'est pas équivalent car il force l'évaluation du côté droit de l'expression. Certains effets secondaires dans ce type d'expression peuvent être terminaux : (!p | (*p == '\0')), lorsque p == NULL. Nous devons le déréférencer pour évaluer l'autre moitié de l'expression.

Cet avertissement ne s'affiche pas si l'opérateur ! est présent sur le côté droit de l'opérateur | car ce cas désigne généralement le cas relativement anodin d'un opérateur incorrect.

Il est difficile d'évaluer la gravité de ce problème sans examiner le code. Ce dernier doit être analysé pour vérifier que le test correct est exécuté.

Cet avertissement indique toujours une confusion possible dans l'utilisation d'un opérateur ou d'une priorité d'opérateur.

Exemple

Le code suivant génère cet avertissement :

void f(int x, int y )
{
  if (!x | y)
  {
    //code 
  }
}

Pour corriger cet avertissement, utilisez l'une des méthodes affichées dans le code suivant :

void fC(int x, int y )
{
  /* When checking whether any bits are set in either x or y. */
  if (!(x | y))
  {
    // code
  }
  /* When checking whether bits are set in either */
  /* the complement of x or in y. */
  if ((~x) | y)
  {
    // code
  }
}

#include <windows.h>
void f(int x, BOOL y )
{
  /* When y is a Boolean or Boolean result. */
  if ((!x) || y)
  {
    // code
  }
}