Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Einem vorzeichenlosen Typ wurde ein unärer Minus-Operator zugewiesen. Das Ergebnis ist weiterhin vorzeichenlos.
Hinweise
Nicht signierte Typen können nur nicht-negative Werte annehmen. In der Regel ist das unäre Minus (Negation) nicht sinnvoll, wenn es auf einen vorzeichenlosen Typ angewendet wird. Sowohl der Operand als auch das Ergebnis sind nicht negativ.
Wenn Sie ein negatives ganzzahliges Literal ausdrücken, wird der - vor dem Wert als unärer Negationsoperator analysiert. Der Compiler wendet den Operator an, nachdem er den numerischen Wert analysiert hat. Wenn der numerische Wert in den Bereich eines nicht signierten ganzzahligen Typs passt, aber nicht den entsprechenden ganzzahligen Typ, interpretiert der Compiler den Wert als nicht signiert.
Diese Warnung tritt häufig auf, wenn Sie versuchen, den Minimalwert int -2147483648 oder den Minimalwert long long -9223372036854775808 auszudrücken. Diese Werte können nicht als -2147483648 oder -9223372036854775808ll geschrieben werden. Der Grund dafür ist, dass der Compiler den Ausdruck in zwei Phasen verarbeitet: Zuerst analysiert er den numerischen Wert und wendet dann den Negationsoperator an. Wenn der Compiler beispielsweise -2147483648 analysiert, führt er die folgenden Schritte aus:
- Die 2147483648 wird ausgewertet. Da es größer als der Maximalwert
intvon 2147483647 ist, aber dennoch in einenunsigned intpasst, istunsigned intder Typ der 2147483648 . - Unär minus wird auf den nicht signierten Wert mit einem nicht signierten Ergebnis angewendet, das auch 2147483648 wird.
Der nicht signierte Typ des Ergebnisses kann zu unerwartetem Verhalten führen. Wenn das Ergebnis in einem Vergleich verwendet wird, kann beispielsweise ein nicht signierter Vergleich verwendet werden, wenn der andere Operand ein int.
Sie können C4146 vermeiden, indem Sie INT_MIN oder LLONG_MIN von <limits.h> oder das C++-Äquivalent, <climits>, verwenden. Diese Werte haben signierte Typen.
Die /sdl Compileroption (Zusätzliche Sicherheitsüberprüfungen aktivieren) erhöht diese Warnung auf einen Fehler.
Beispiel
Das folgende Beispiel zeigt das unerwartete Verhalten, das auftreten kann, wenn der Compiler die Warnung C4146 generiert:
// 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 diesem Beispiel berücksichtigt der Compiler -9223372036854775808ll nicht signiert, obwohl das Literal über ein ll Suffix verfügt und der Negationsoperator angewendet wird. Um den < Vergleich vorzunehmen, wird vom Compiler im Hintergrund signiert auf iunsigned long long int . Die erwartete zweite Zeile , 1 is greater than the most negative long long intwird nicht gedruckt, weil ((unsigned long long int)1) > 9223372036854775808ull "false" ist.
Um das Beispiel zu beheben, schließen <climits> Sie -9223372036854775808ll ein, und ändern Sie es in LLONG_MIN.