Поделиться через


C6291

Обновлен: Ноябрь 2007

C6291

Предупреждение C6291. Битовая операция над логическим результатом: ! имеет более высокий приоритет, чем |. Используйте вместо этого || или (!(x | y))

Оператор ! возвращает логическое значение, а оператор | (побитовое ИЛИ) принимает два арифметических аргумента. Кроме того, оператор ! имеет более высокий приоритет, чем оператор |.

Поэтому обнаружена одна из следующих ошибок.

  • Неправильное использование скобок в выражении

    Поскольку результатом оператора ! является логическое значение (ноль или один), попытка проверки совпадения битов двух переменных сводится к проверке того, что в правой стороне присутствует наименьший бит: ((!x) | y) != (!(x | y)), где x == 0 и y == 1.

  • Оператор ! используется здесь неверно, и его следует заменить на оператор ~.

    Оператор ! возвращает логическое значение, тогда как оператор ~ возвращает арифметический результат. Эти операторы не являются взаимозаменяемыми даже в том случае, если применяются к логическому значению (ноль или один): ((!x) | y) != ((~x) | y), если x == 1 и y == 0.

  • Бинарный оператор | используется неверно, и его следует заменить на оператор ||.

    Иногда операторы | и || можно применять в одних и тех же ситуациях, однако они не являются эквивалентными, поскольку при использовании первого оператора выполняется принудительное вычисление правой стороны выражения. В результате использования такого рода выражений могут возникать определенные побочные эффекты: (!p | (*p == '\0')), если p == NULL, то для вычисления второй половины выражения требуется разыменовать это значение.

Данное предупреждение не выводится, если оператор ! находится в правой стороне оператора |, поскольку это относительно безобидный случай неверного оператора.

Серьезность данной проблемы можно определить только после изучения кода. Следует исследовать код и убедиться в выполнении именно той проверки, которая предполагалась.

Данное предупреждение всегда указывает на возможную неоднозначность в использовании оператора или порядка применения операторов.

Пример

Данное предупреждение создается в следующем коде:

void f(int x, int y )
{
  if (!x | y)
  {
    //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
  }
}