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


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