Avertissement C6291

Opération au niveau du bit sur le résultat logique : ! a une priorité supérieure à |. Utiliser || ou ( !( x | y)) à la place

L’opérateur ! génère un résultat booléen, et l’opérateur | (au niveau du bit ou) prend 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 est mal entre parenthèses :

    Étant donné que le résultat est ! booléen (zéro ou un), une tentative de test que deux variables ont un jeu de bits ne finira que par tester que le bit le plus bas est présent dans le côté droit : ((!x) | y) != (!(x | y)) quand x == 0 et y == 1.

  • L’opérateur ! est incorrect et doit être à ~ la place :

    L’opérateur ! a un résultat booléen, mais l’opérateur ~ a un résultat arithmétique. Ces opérateurs ne sont jamais interchangeables, même en cas d’exploitation sur une valeur booléenne (zéro ou un) : ((!x) | y) != ((~x) | y) quand x == 1 et y == 0.

  • L’opérateur | binaire est incorrect et doit être à la place ||:

    Même s’il | peut parfois être échangé 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')), quand p == NULL, nous devons le déréférer pour évaluer l’autre moitié de l’expression.

Cet avertissement n’est pas signalé si l’opérateur ! se trouve sur le côté droit de l’opérateur | , car ce cas n’est généralement que le cas relativement inoffensif d’un opérateur incorrect.

Il est difficile de juger de la gravité de ce problème sans examiner le code. Le code doit être inspecté pour s’assurer que le test prévu se produit.

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

Nom de l’analyse du code : LOGICALNOTBITWISEOR

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’un des exemples présentés 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
  }
}