Advertencia C6291

Operación bit a bit en el resultado lógico: ! tiene mayor prioridad que |. Use en su lugar || o (!(x | y))

El operador ! produce un resultado booleano y el operador | (OR bit a bit) toma dos argumentos aritméticos. El !operador tiene mayor prioridad que |.

Por lo tanto, se ha detectado uno de los siguientes errores:

  • La expresión está entre paréntesis:

    Dado que el resultado de ! es booleano (cero o uno), cualquier intento de probar que dos variables tienen bits establecidos solo acabará probando que el bit más bajo está presente en el lado derecho: ((!x) | y) != (!(x | y)) cuando x == 0 y y == 1.

  • El operador ! es incorrecto y debe ser un valor ~ en su lugar:

    El operador ! tiene un resultado booleano, mientras que el operador ~ tiene un resultado aritmético. Estos operadores no se pueden intercambiar, incluso cuando funcionan en un valor booleano (cero o uno): ((!x) | y) != ((~x) | y) cuando x == 1 y y == 0.

  • El operador binario | es incorrecto, debería ser ||:

    | Aunque a veces se puede intercambiar con ||, no es equivalente porque fuerza la evaluación del lado derecho de la expresión. Algunos efectos secundarios de este tipo de expresión puede ser terminal: (!p | (*p == '\0')), cuando p == NULL, es necesario desreferenciarlo para evaluar la otra mitad de la expresión.

Esta advertencia no se notifica si el ! operador está en el lado derecho del | operador porque este caso suele ser solo el caso relativamente inofensivo de un operador incorrecto.

Es difícil juzgar la gravedad de este problema sin examinar el código. El código debe inspeccionarse para asegurarse de que funciona según lo previsto.

Esta advertencia siempre indica una posible confusión en el uso de un operador o una prioridad de operadores.

Nombre del análisis de código: LOGICALNOTBITWISEOR

Ejemplo

El código siguiente genera esta advertencia:

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

Para corregir esta advertencia, use uno de los ejemplos que se muestran en el código siguiente:

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
  }
}