Upozornění kompilátoru (úroveň 2) C4146

unární mínus operátor použitý na nepodepsaný typ, výsledek je stále nepodepsaný

Nepodepsané typy můžou obsahovat pouze nezáporné hodnoty, takže unární minus (negation) obvykle při použití u nepodepsaného typu nedává smysl. Operand i výsledek jsou nezáporné.

Poznámky

Při vyjádření záporného celočíselného literálu - se před hodnotou parsuje jako operátor unární negace . Kompilátor použije operátor po parsování číselné hodnoty. Pokud se číselná hodnota vejde do rozsahu celočíselného typu bez znaménka, ale ne odpovídající typ celého čísla se znaménkem, kompilátor interpretuje hodnotu jako nepodepsanou. Unsigned value is unchanged by unary negation operator.

K tomuto upozornění často dochází, když se pokusíte vyjádřit minimální int hodnotu, -2147483648 nebo minimální long long hodnotu , -9223372036854775808. Tyto hodnoty nelze zapsat jako -2147483648 nebo -9223372036854775808ll. Důvodem je to, že kompilátor zpracovává výraz ve dvou fázích: nejprve parsuje číselnou hodnotu a pak použije operátor negace. Když například kompilátor parsuje -2147483648, postupuje takto:

  1. Vyhodnotí se číslo 2147483648. Protože je větší než maximální int hodnota 2147483647, ale přesto se vejde do unsigned int, typ 2147483648 je unsigned int.

  2. Unární mínus se použije na hodnotu bez znaménka s výsledkem bez znaménka, který se také stane 2147483648.

Nepodepsaný typ výsledku může způsobit neočekávané chování. Pokud je výsledek použit v porovnání, pak se může použít nepodepsané porovnání, například když druhý operand je .int

C4146 se můžete vyhnout použitím INT_MIN nebo LLONG_MIN ekvivalentem <limits.h> jazyka C++ nebo z jazyka C++. <climits> Tyto hodnoty mají podepsané typy.

Možnost kompilátoru /sdl (Povolit další kontroly zabezpečení) zvýší toto upozornění na chybu.

Příklad

Následující ukázka ukazuje neočekávané chování, ke kterému může dojít při generování upozornění C4146 kompilátoru:

// 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);
}

V tomto příkladu kompilátor považuje -9223372036854775808ll bez znaménka, i když literál má ll příponu a použije se operátor negace. Aby bylo < porovnání, kompilátor bezobslužně podporuje podepsáno i .unsigned long long int Očekávaný druhý řádek 1 is greater than the most negative long long int, není vytištěn, protože ((unsigned long long int)1) > 9223372036854775808ull je false.

Pokud chcete tento příklad opravit, zahrňte <climits> a změňte -9223372036854775808ll na LLONG_MIN.

Viz také

Unární negační operátor (-)