Übliche arithmetische Konvertierungen
Viele binäre Operatoren, die Operanden vom arithmetischen oder Aufzählungstyp erwarten, führen Konvertierungen durch und liefern auf ähnliche Weise Ergebnistypen. Der Zweck ist, einen gemeinsamen Typ zu erzielen, der auch der Typ des Ergebnisses ist. Dieses Muster wird als die üblichen arithmetischen Konvertierungen bezeichnet.
Inhalt |
[bearbeiten] Definition
Die üblichen arithmetischen Konvertierungen sind wie folgt definiert
[bearbeiten] Stufe 1
Auf beide Operanden wird eine Lvalue-zu-Rvalue-Konvertierung angewendet. Die resultierenden prvalues werden anstelle der ursprünglichen Operanden für den restlichen Prozess verwendet.
[bearbeiten] Stufe 2
|
(seit C++11) |
[bearbeiten] Stufe 3
|
(seit C++26) |
[bearbeiten] Stufe 4
- Wenn einer der Operanden vom Typ Floating-point Type ist, werden die folgenden Regeln angewendet
- Wenn beide Operanden denselben Typ haben, wird keine weitere Konvertierung durchgeführt.
- Andernfalls, wenn einer der Operanden von einem Nicht-Gleitkommatyp ist, wird dieser Operand in den Typ des anderen Operanden konvertiert.
- Andernfalls, wenn die Gleitkommakonvertierungsränge der Typen der Operanden geordnet, aber(seit C++23) nicht gleich sind, dann wird der Operand vom Typ mit dem geringeren Gleitkommakonvertierungsrang in den Typ des anderen Operanden konvertiert.
|
(seit C++23) |
- Andernfalls sind beide Operanden von Ganzzahltypen, und es wird mit der nächsten Stufe fortgefahren.
[bearbeiten] Stufe 5
Beide Operanden werden in einen gemeinsamen Typ C konvertiert. Gegeben die Typen T1 und T2 als der beförderte Typ (gemäß den Regeln der Integral Promotion) der Operanden, werden die folgenden Regeln angewendet, um C zu bestimmen
- Wenn
T1undT2derselben Typ sind, istCdieser Typ. - Andernfalls, wenn
T1undT2beide vorzeichenbehaftete Ganzzahltypen oder beide vorzeichenlose Ganzzahltypen sind, istCder Typ mit dem größeren Rang der Ganzzahlkonvertierung. - Andernfalls ist ein Typ zwischen
T1undT2ein vorzeichenbehafteter GanzzahltypSund der andere Typ ist ein vorzeichenloser GanzzahltypU. Wenden Sie die folgenden Regeln an
- Wenn der Rang der Ganzzahlkonvertierung von
Ugrößer oder gleich dem Rang der Ganzzahlkonvertierung vonSist, istCU. - Andernfalls, wenn
Salle Werte vonUdarstellen kann, istCS. - Andernfalls ist
Cder vorzeichenlose Ganzzahltyp, derSentspricht.
- Wenn der Rang der Ganzzahlkonvertierung von
|
Wenn ein Operand vom Enumerationstyp und der andere Operand von einem anderen Enumerationstyp oder einem Gleitkommatyp ist, ist dieses Verhalten veraltet. |
(seit C++20) (bis C++26) |
[bearbeiten] Rang der Ganzzahlkonvertierung
Jeder Ganzzahltyp hat einen Rang der Ganzzahlkonvertierung, der wie folgt definiert ist
- Keine zwei vorzeichenbehafteten Ganzzahltypen außer char und signed char (wenn char vorzeichenbehaftet ist) haben denselben Rang, auch wenn sie dieselbe Darstellung haben.
- Der Rang eines vorzeichenbehafteten Ganzzahltyps ist größer als der Rang eines jeden vorzeichenbehafteten Ganzzahltyps mit geringerer Breite.
- Die Ränge der folgenden Ganzzahltypen nehmen in der Reihenfolge ab
|
(seit C++11) |
- long
- int
- short
- signed char
- Der Rang eines jeden vorzeichenlosen Ganzzahltyps entspricht dem Rang des entsprechenden vorzeichenbehafteten Ganzzahltyps.
|
(seit C++11) |
- Der Rang von bool ist kleiner als der Rang aller Standard-Ganzzahltypen.
- Die Ränge von Codierungszeichentypen (char , char8_t(seit C++20), char16_t, char32_t,(seit C++11) und wchar_t) entsprechen den Rängen ihrer zugrunde liegenden Typen, was bedeutet
- Der Rang von char entspricht dem Rang von signed char und unsigned char.
|
(seit C++20) |
|
(seit C++11) |
- Der Rang von wchar_t entspricht dem Rang seines implementierungsdefinierten zugrunde liegenden Typs.
|
(seit C++11) |
- Für alle Ganzzahltypen
T1,T2undT3gilt: WennT1einen größeren Rang alsT2undT2einen größeren Rang alsT3hat, dann hatT1einen größeren Rang alsT3.
Der Rang der Ganzzahlkonvertierung wird auch in der Definition der Integral Promotion verwendet.
[bearbeiten] Gleitkommakonvertierungsrang und Unterrang
[bearbeiten] Gleitkommakonvertierungsrang
Jeder Gleitkommatyp hat einen Gleitkommakonvertierungsrang, der wie folgt definiert ist
- Die Ränge der Standard-Gleitkommatypen nehmen in der Reihenfolge ab
- long double
- double
- float
|
(seit C++23) |
GleitkommakonvertierungsunterrangGleitkommatypen, die gleiche Gleitkommakonvertierungsränge haben, werden nach dem Gleitkommakonvertierungsunterrang geordnet. Der Unterrang bildet eine Totalordnung unter Typen mit gleichen Rängen. Die Typen |
(seit C++23) |
[bearbeiten] Verwendung
Der Gleitkommakonvertierungsrang und der Unterrang werden auch verwendet, um
- zu bestimmen, ob eine Konvertierung zwischen verschiedenen Gleitkommatypen implizit erfolgen kann oder eine schmalende Konvertierung ist,
- die Konvertierungssequenzen bei der Überladungsauflösung zu unterscheiden,
|
(seit C++23) |
- zu bestimmen, ob der konvertierende Konstruktor von std::complex explizit ist, oder
- den gemeinsamen Gleitkommatyp zu bestimmen, wenn Argumente unterschiedlicher Gleitkommatypen an gemeinsame oder spezielle mathematische Funktionen übergeben werden.
[bearbeiten] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| CWG 1642 | C++98 | übliche arithmetische Konvertierungen können Lvalues beinhalten | wenden Lvalue-zu-Rvalue-Konvertierungen zuerst an |
| CWG 2528 | C++20 | der Drei-Wege-Vergleich zwischen unsigned char und unsigned int ist fehlerhaft, da die Zwischen-Integral-Promotion[1] |
bestimmt den gemeinsamen Typ basierend auf den beförderten Typen, ohne die Operanden tatsächlich zu befördern[2] |
| CWG 2892 | C++98 | wenn beide Operanden vom selben Gleitkommatyp sind, war die Bedeutung von „keine weitere Konvertierung nötig“ unklar |
geändert zu „keine weitere Konvertierung wird durchgeführt“ |
- ↑ Vor der Auflösung wird unsigned char zu Beginn von Stufe 5 zu int befördert und dann in unsigned int konvertiert. Die letztere Konvertierung ist jedoch schmalend, was den Drei-Wege-Vergleich fehlerhaft macht.
- ↑ Nach der Auflösung ist der gemeinsame Typ immer noch unsigned int. Der Unterschied besteht darin, dass unsigned char direkt in unsigned int konvertiert wird, ohne die Zwischen-Integral-Promotion. Die Konvertierung ist nicht schmalend und daher ist der Drei-Wege-Vergleich wohlgeformt.