C6291

warning C6291: Bitwise operation on logical result: ! has higher precedence than |. Use || or (!(x | y)) instead

The ! operator yields a Boolean result, and the | (bitwise-or) operator takes two arithmetic arguments. The ! operator also has higher precedence than |.

Therefore, one of the following errors has been detected:

  • The expression is mis-parenthesised:

    Because the result of ! is Boolean (zero or one), an attempt to test that two variables have bits set will only end up testing that the lowest bit is present in the right side: ((!x) | y) != (!(x | y)) when x == 0 and y == 1.

  • The ! operator is incorrect, and should be a ~ instead:

    The ! operator has a Boolean result, but the ~ operator has an arithmetic result. These operators are never interchangeable, even when operating on a Boolean value (zero or one): ((!x) | y) != ((~x) | y) when x == 1 and y == 0.

  • The binary operator | is incorrect, and should instead be ||:

    Even though | can sometimes be interchanged with ||, it is not equivalent because it forces evaluation of the right side of the expression. Certain side-effects in this type of expression can be terminal: (!p | (*p == '\0')), when p == NULL, we must dereference it to evaluate the other half of the expression.

This warning is not reported if the ! operator is on the right side of the | operator because this case is typically just the relatively harmless case of an incorrect operator.

It is difficult to judge the severity of this problem without examining the code. The code should be inspected to ensure that the intended test is occurring.

This warning always indicates possible confusion in the use of an operator or operator precedence.

Example

The following code generates this warning:

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

To correct this warning, use one of the methods shown in the following code:

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