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