Condividi tramite


Avviso C6291

Operazione bit per bit sul risultato logico: ! ha una precedenza superiore a |. Usare || o (!( x | y))

L'operatore ! restituisce un risultato booleano e l'operatore | (bit per bit o) accetta due argomenti aritmetici. L'operatore ! ha anche una precedenza superiore a |.

Di conseguenza, è stato rilevato uno degli errori seguenti:

  • L'espressione non è racchiusa tra parentesi:

    Poiché il risultato di ! è booleano (zero o uno), un tentativo di testare che due variabili hanno bit impostati finirà solo per verificare che il bit più basso sia presente sul lato destro: ((!x) | y) != (!(x | y)) quando x == 0 e y == 1.

  • L'operatore ! non è corretto e deve essere invece:~

    L'operatore ! ha un risultato booleano, ma l'operatore ~ ha un risultato aritmetico. Questi operatori non sono mai intercambiabili, anche quando si opera su un valore booleano (zero o uno): ((!x) | y) != ((~x) | y) quando x == 1 e y == 0.

  • L'operatore | binario non è corretto e deve essere ||:

    Anche se | a volte può essere interscambiato con ||, non è equivalente perché forza la valutazione del lato destro dell'espressione. Alcuni effetti collaterali in questo tipo di espressione possono essere terminal: , (!p | (*p == '\0'))quando p == NULL, è necessario dereferenziarlo per valutare l'altra metà dell'espressione.

Questo avviso non viene segnalato se l'operatore ! si trova sul lato destro dell'operatore | perché questo caso è in genere solo il caso relativamente innocuo di un operatore non corretto.

È difficile giudicare la gravità di questo problema senza esaminare il codice. Il codice deve essere controllato per assicurarsi che si verifichi il test previsto.

Questo avviso indica sempre una possibile confusione nell'uso di un operatore o di una precedenza dell'operatore.

Nome dell'analisi del codice: LOGICALNOTBITWISEOR

Esempio

Il codice seguente genera questo avviso:

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

Per correggere questo avviso, usare uno degli esempi illustrati nel codice seguente:

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