Dieser Ausdruck findet sich im Beispiel in §8.5.4 / 7 im Standard (N3797)
%Vor%Gegeben §8.5.4 / 7 und seinen vierten Aufzählungspunkt:
Eine einschränkende Konvertierung ist eine implizite Konvertierung:
- von einem Integer-Typ oder einem Unscoped-Aufzählungstyp zu einem Integer-Typ, der nicht alle Werte des Originaltyps darstellen kann, außer wo die Quelle ein konstanter Ausdruck ist, dessen Wert nach Integrale Promotions passen in den Zieltyp.
Ich würde sagen, dass es hier keine Verengung gibt, da -1 ein konstanter Ausdruck ist, dessen Wert nach der Integral-Promotion in einen unsigned int passt.
Siehe auch §4.5 / 1 über Integrale Werbung :
Ein Pr-Wert eines anderen Integer-Typs als bool, char16_t, char32_t oder wchar_t, dessen Ganzzahlumwandlungsrang (4.13) kleiner ist als der Rang von int kann in einen prvalue vom Typ int konvertiert werden, wenn int alle darstellen kann die Werte des Quelltyps; Andernfalls kann der Quellprwert sein konvertiert in einen prvalue vom Typ unsigned int.
Ab 4.13 haben wir den Rang von -1 (ein int) ist gleich dem Rang eines vorzeichenlosen int, und so kann es in einen vorzeichenlosen int konvertiert werden.
Bearbeiten
Leider Jerry Coffin hat seine Antwort aus diesem Thread entfernt. Ich glaube, er war auf dem richtigen Weg, wenn wir die Tatsache akzeptieren, dass die aktuelle Lektüre des vierten Aufzählungspunkts in §8.5.4 / 7 falsch ist, danach ändern im Standard.
Die Änderung des Wortlauts der Norm soll das Verständnis bestätigen, dass die Konvertierung eines negativen Wertes in einen vorzeichenlosen Typ immer eine engere Umwandlung war.
Informell kann -1 nicht innerhalb des Bereichs eines vorzeichenlosen Typs dargestellt werden, und das Bitmuster, das es darstellt, stellt nicht denselben Wert dar, wenn es in einem unsigned int gespeichert wird. Es handelt sich also um eine sich verengende Conversion und eine Promotion / Erweiterung ist nicht involviert.
Hier geht es um die zierliche Kunst, den Standard zu lesen. Wie üblich, weiß der Compiler es am besten.
Es gibt keine integrale Werbung von int
bis unsigned int
, daher ist es immer noch schlecht formatiert.
Das wäre eine integrale Konvertierung .
Die Eingrenzung ist eine implizite Konvertierung von einem Integer-Typ in einen Integer-Typ, der nicht alle Werte des Originaltyps darstellen kann
Die Konvertierung vom Integer-Typ int
in den Integer-Typ unsigned int
kann natürlich nicht alle Werte des ursprünglichen Typs darstellen - der Standard ist hier ziemlich eindeutig. Wenn Sie es wirklich brauchen, können Sie
Dies funktioniert ohne Fehler / Warnungen, da 1u
ein Literal vom Typ unsigned int
ist, das dann negiert wird. Dies ist in den Standardzuständen als [expr.unary.op] definiert:
Das Negativ einer vorzeichenlosen Größe wird berechnet, indem der Wert von 2 n subtrahiert wird, wobei n die Anzahl der Bits im beförderten Operanden ist.
-1
ist jedoch ein int
vor und nach der Negation und daher wird es eine sich verengende Umwandlung. Es gibt keine negativen Literale ; Einzelheiten finden Sie diese Antwort .
Promotion kopiert informell den gleichen Wert in einen größeren Bereich, daher sollte er hier nicht verwechselt werden, da die Größen (von signed
und unsigned
) gleich sind. Selbst wenn Sie versuchen, es in einen größeren Typ zu konvertieren, sagen wir unsigned long long
, ist es immer noch eine einschränkende Umwandlung, da es keine negative Zahl wirklich darstellen kann.
Tags und Links c++ c++11 language-lawyer narrowing