Dela via


Kompilatorvarning (nivå 2) C4146

Enär minusoperator tillämpas på en osignerad typ, förblir resultatet osignerat

Anmärkningar

Osignerade typer innehåller endast icke-negativa värden. Unärt minus (negation) är vanligtvis inte meningsfullt när det tillämpas på en osignerad datatyp. Både operanden och resultatet är icke-negativa.

När du uttrycker en negativ heltalsliteral parsas - vid värdet som en unär negationsoperator. Kompilatorn tillämpar operatorn när den parsar det numeriska värdet. Om det numeriska värdet passar i intervallet för en osignerad heltalstyp, men inte motsvarande signerade heltalstyp, tolkar kompilatorn värdet som osignerat.

Den här varningen inträffar ofta när du försöker uttrycka det lägsta int värdet, -2147483648 eller det lägsta long long värdet, -9223372036854775808. Dessa värden kan inte skrivas som -2147483648 eller -9223372036854775808ll. Orsaken är att kompilatorn bearbetar uttrycket i två steg: först parsar det numeriska värdet och sedan negationsoperatorn. När kompilatorn till exempel parsar -2147483648 följer den dessa steg:

  1. Antalet 2147483648 utvärderas. Eftersom det är större än det maximala int värdet för 2147483647, men fortfarande passar i en unsigned int, är unsigned inttypen av 2147483648 .
  2. Unary minus tillämpas på det osignerade värdet, med ett osignerat resultat, som också råkar vara 2147483648.

Den osignerade typen av resultat kan orsaka oväntat beteende. Om resultatet används i en jämförelse kan en osignerad jämförelse användas, till exempel när den andra operanden är en int.

Du kan undvika C4146 med hjälp INT_MIN av eller LLONG_MIN från <limits.h> eller C++-motsvarigheten, <climits>. Dessa värden har signerade typer.

Kompileringsalternativet (Aktivera ytterligare säkerhetskontroller) höjer varningen till ett fel./sdl

Exempel

I följande exempel visas det oväntade beteende som kan inträffa när kompilatorn genererar varning 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);
}

I det här exemplet tar kompilatorn hänsyn till -9223372036854775808ll osignerad trots att literalen har ett ll suffix och negationsoperatorn tillämpas. För att göra jämförelsen < höjer kompilatorn tyst upp signerad i till unsigned long long int. Den förväntade andra raden, 1 is greater than the most negative long long int, skrivs inte ut eftersom ((unsigned long long int)1) > 9223372036854775808ull den är falsk.

Åtgärda exemplet genom att inkludera <climits> och ändra -9223372036854775808ll till LLONG_MIN.

Se även

Enställig negationsoperator (-)