Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
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:
- Antalet 2147483648 utvärderas. Eftersom det är större än det maximala
intvärdet för 2147483647, men fortfarande passar i enunsigned int, ärunsigned inttypen av 2147483648 . - 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.