共用方式為


C6291

警告 C6291: 邏輯結果的位元運算: ! 的優先順序高於 |。請改用 || 或 (!(x | y))

! 運算子會產生布林結果,而 | (位元 OR) 運算子則會採用兩個算術引數。! 運算子的優先順序也高於 |.

因此,會偵測到下列其中一個錯誤:

  • 運算式的括號位置錯誤:

    因為 ! 的結果是布林 (零或一),所以嘗試對具有位元的兩個變數進行測試,只會讓這兩者的最低位元成為測試結果,出現在運算式右邊:當 x == 0 且 y == 1 時 ((!x) | y) != (!(x | y))。

  • ! 運算子不正確,且應改為 ~:

    ! 運算子具有布林結果,但 ~ 運算子具有算術結果。這些運算子絕不可互換,即使是以布林值 (零或一) 作業也一樣:當 x == 1 且 y == 0 時 ((!x) | y) != ((~x) | y)。

  • 二元運算子 | 不正確,且應改為 ||:

    雖然 | 有時候可以和 || 互換,但是前者並不是對等項目,因為它會強制評估運算式的右邊。這類運算式的特定副作用 (Side Effect) 會造成無法再修改的結果:(!p | (*p == '\0')),而在 p == NULL 時,必須取它的值以評估運算式的另一半。

如果 ! 運算子是在 | 運算子的右邊 (這種情況一般只是相當無害之不正確運算子的情況),則不會報告這個警告。

如果不檢查程式碼,會很難判斷此問題的嚴重性。應該檢查程式碼,以確保會發生所要的測試。

這個警告一律表示在使用運算子或運算子優先順序 (Operator Precedence) 可能會發生混淆。

範例

下列程式碼將產生出這個警告:

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