Warum charakterisiert der folgende Ausdruck eine einschränkende Umwandlung?

8

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.

    
Wake up Brazil 20.01.2014, 19:04
quelle

3 Antworten

1

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.

    
david.pfx 21.01.2014, 14:03
quelle
7

Es gibt keine integrale Werbung von int bis unsigned int , daher ist es immer noch schlecht formatiert.

Das wäre eine integrale Konvertierung .

    
Johannes Schaub - litb 20.01.2014 19:07
quelle
1
  

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

tun %Vor%

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.

    
legends2k 20.01.2014 19:12
quelle