Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Operatore unario meno applicato al tipo senza segno, risultato ancora senza segno
Osservazioni:
I tipi senza segno contengono solo valori non negativi. Pertanto, il meno unario (negazione) generalmente non ha senso quando è applicato a un tipo senza segno. Sia l'operando che il risultato sono non negativi.
Quando si esprime un valore letterale intero negativo, l'oggetto - davanti al valore viene analizzato come operatore di negazione unario . Il compilatore applica l'operatore dopo l'analisi del valore numerico. Se il valore numerico rientra nell'intervallo di un tipo integer senza segno, ma non nel tipo intero con segno corrispondente, il compilatore interpreta il valore come senza segno.
Questo avviso si verifica spesso quando si tenta di esprimere il valore minimo int , -2147483648 o il valore minimo long long , -9223372036854775808. Questi valori non possono essere scritti come -2147483648 o -9223372036854775808ll. Il motivo è che il compilatore elabora l'espressione in due fasi: prima analizza il valore numerico, quindi applica l'operatore di negazione. Ad esempio, quando il compilatore analizza -2147483648, segue questa procedura:
- Il numero 2147483648 viene valutato. Poiché è maggiore del valore massimo
intdi 2147483647, ma rientra ancora in ununsigned intoggetto , il tipo di 2147483648 èunsigned int. - Unario meno viene applicato al valore senza segno, con un risultato senza segno, che si verifica anche 2147483648.
Il tipo non firmato del risultato può causare un comportamento imprevisto. Se il risultato viene usato in un confronto, è possibile usare un confronto senza segno, ad esempio quando l'altro operando è .int
È possibile evitare C4146 usando INT_MIN o LLONG_MIN da <limits.h> o dall'equivalente C++, <climits>. Questi valori hanno tipi firmati.
L'opzione del /sdl compilatore (Abilita controlli di sicurezza aggiuntivi) eleva questo avviso a un errore.
Esempio
L'esempio seguente illustra il comportamento imprevisto che può verificarsi quando il compilatore genera l'avviso 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);
}
In questo esempio, il compilatore considera -9223372036854775808ll unsigned anche se il valore letterale ha un ll suffisso e viene applicato l'operatore di negazione. Per eseguire il confronto, il compilatore promuove automaticamente l'accesso < a iunsigned long long int. La seconda riga prevista, 1 is greater than the most negative long long int, non viene stampata perché ((unsigned long long int)1) > 9223372036854775808ull è false.
Per correggere l'esempio, includere <climits> e modificare -9223372036854775808ll in LLONG_MIN.