共用方式為


編譯器警告 (層級 2) C4146

一元減號運算子套用 unsigned 類型,所得的結果也會是 unsigned 類型

不帶正負號的類型只能保存非負值,因此一元減號(負號)在套用至不帶正負號的類型時通常沒有意義。 操作數和結果都是非負數。

備註

當您表示負整數常值時, - 值前面的 會剖析為 一元否定 運算符。 編譯程式會在剖析數值之後套用 運算元。 如果數值符合無符號整數類型的範圍,但不符合對應的帶正負號整數類型,編譯程式會將值解譯為不帶正負號。 一元負號運算子不會變更不帶正負號的值。

當您嘗試表示最小值 int -2147483648 或最小值 long long -9223372036854775808 時,通常會發生此警告。 這些值不能分別寫入為 -2147483648 或 -9223372036854775808ll。 原因是編譯程式會以兩個階段處理表達式:首先,它會剖析數值,然後套用否定運算符。 例如,當編譯程式剖析 -2147483648時,它會遵循下列步驟:

  1. 會評估2147483648數目。 因為它大於2147483647的最大值 int ,但仍符合 unsigned int,所以 2147483648 的類型為 unsigned int

  2. 一元減號會套用至不帶正負號的值,併產生不帶正負號的結果,這也會發生2147483648。

結果的不帶正負號類型可能會導致非預期的行為。 如果在比較中使用結果,則當另一個操作數是 int時,可能會使用不帶正負號的比較。

您可以使用 或 LLONG_MIN C++對等<climits>的 或 ,<limits.h>來避免 C4146INT_MIN。 這些值具有帶正負號的類型。

/sdl (啟用額外安全性檢查) (部分機器翻譯) 編譯器選項會將這個警告升級為錯誤。

範例

下列範例示範編譯程序產生警告 C4146 時可能發生的非預期行為:

// C4146.cpp
// compile with: /W2
#include <iostream>

void check(int i)
{
    if (i > -9223372036854775808ll)   // C4146
        std::cout << i << " is greater than the most negative long long int.\n";
}

int main()
{
    check(-100);
    check(1);
}

在此範例中,編譯程式會考慮 -9223372036854775808ll不帶正負號,即使常值具有 ll 後綴,而且會套用否定運算符。 為了進行 < 比較,編譯程式會以無訊息方式將已簽署 i 的 升級為 unsigned long long int。 預期的第二行 1 is greater than the most negative long long int不會列印,因為 ((unsigned long long int)1) > 9223372036854775808ull 為 false。

若要修正範例,請將 -9223372036854775808ll 包含 <climits> 並變更為 LLONG_MIN

另請參閱

一元負運算符 (-)