Usual arithmetic conversions
Viele binäre Operatoren, die Operanden vom Typ arithmetic oder enumeration erwarten, verursachen Konvertierungen und ergeben Ergebnistypen auf ähnliche Weise. Das Ziel ist es, einen gemeinsamen Typ zu erzeugen, der auch der Typ des Ergebnisses ist. Dieses Muster wird als usual arithmetic conversions bezeichnet.
Inhaltsverzeichnis |
Definition
Übliche arithmetische Konvertierungen sind wie folgt definiert:
Stufe 1
Wendet auf beide Operanden eine Lvalue-zu-Rvalue-Konvertierung an, die resultierenden Prvalues werden anstelle der ursprünglichen Operanden für den weiteren Prozess verwendet.
Stufe 2
|
(since C++11) |
Stufe 3
|
(since C++26) |
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 einen Nicht-Gleitkommatyp hat, wird dieser Operand in den Typ des anderen Operanden konvertiert.
- Andernfalls, wenn die Gleitkomma-Konvertierungsränge der Typen der Operanden geordnet aber (seit C++23) nicht gleich sind, dann wird der Operand des Typs mit dem niedrigeren Gleitkomma-Konvertierungsrang in den Typ des anderen Operanden konvertiert.
|
(since C++23) |
- Andernfalls sind beide Operanden von ganzzahligen Typen, fahren Sie mit der nächsten Stufe fort.
Stufe 5
Beide Operanden werden in einen gemeinsamen Typ
C
konvertiert. Unter der Annahme der Typen
T1
und
T2
als die höherstufigen Typen (
gemäß den Regeln der Ganzzahlaufwertung
) der Operanden, werden die folgenden Regeln angewendet, um
C
zu bestimmen:
-
Wenn
T1undT2denselben Typ haben, istCdieser Typ. -
Andernfalls, wenn
T1undT2beide vorzeichenbehaftete Ganzzahltypen oder beide vorzeichenlose Ganzzahltypen sind, istCder Typ mit dem höheren Integer-Konvertierungsrang . -
Andernfalls ist einer der Typen zwischen
T1undT2ein vorzeichenbehafteter GanzzahltypS, der andere Typ ist ein vorzeichenloser GanzzahltypU. Wende die folgenden Regeln an:
-
-
Wenn der Integer-Konvertierungsrang von
Ugrößer oder gleich dem Integer-Konvertierungsrang vonSist, istCgleichU. -
Andernfalls, wenn
Salle Werte vonUdarstellen kann, istCgleichS. -
Andernfalls
ist
Cder vorzeichenlose Integer-Typ, derSentspricht.
-
Wenn der Integer-Konvertierungsrang von
|
Wenn ein Operand vom Aufzählungstyp ist und der andere Operand von einem anderen Aufzählungstyp oder einem Gleitkommatyp, ist dieses Verhalten als veraltet markiert. |
(since C++20)
(until C++26) |
Integer-Umwandlungsrang
Jeder Integer-Typ hat einen Integer-Konvertierungsrang , der wie folgt definiert ist:
- Keine zwei vorzeichenbehafteten Ganzzahltypen außer char und signed char (falls char vorzeichenbehaftet ist) haben denselben Rang, selbst wenn sie dieselbe Darstellung haben.
- Der Rang eines vorzeichenbehafteten Ganzzahltyps ist größer als der Rang jedes vorzeichenbehafteten Ganzzahltyps mit einer geringeren Breite.
- Die Ränge der folgenden Ganzzahltypen nehmen in dieser Reihenfolge ab:
|
(seit C++11) |
-
- long
- int
- short
- signed char
- Der Rang jedes vorzeichenlosen Ganzzahltyps entspricht dem Rang des entsprechenden vorzeichenbehafteten Ganzzahltyps.
|
(since C++11) |
- Der Rang von bool ist geringer als der Rang aller Standard-Ganzzahltypen.
- Die Ränge der Zeichenkodierungstypen ( char , char8_t (seit C++20) , char16_t , char32_t , (seit C++11) und wchar_t ) entsprechen den Rängen ihrer zugrundeliegenden 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 zugrundeliegenden Typs.
|
(since C++11) |
-
Für alle ganzzahligen Typen
T1,T2undT3, wennT1einen höheren Rang alsT2hat undT2einen höheren Rang alsT3hat, dann hatT1einen höheren Rang alsT3.
Der Integer-Umwandlungsrang wird auch in der Definition der integral promotion verwendet.
Floating-Point-Umwandlungsrang und Unterrang
Rang der Gleitkomma-Konvertierung
Jeder Gleitkommatyp hat einen Gleitkomma-Konvertierungsrang , der wie folgt definiert ist:
-
Die Rangfolge der Standard-Gleitkommatypen nimmt in dieser Reihenfolge ab:
- long double
- double
- float
|
(seit C++23) |
Floating-Point-Konvertierungs-SubrangGleitkommatypen mit gleichem Gleitkomma-Konvertierungsrang werden nach ihrem Gleitkomma-Konvertierungs-Subrang geordnet. Der Subrang bildet eine Totalordnung zwischen Typen mit gleichem Rang.
Die Typen
|
(seit C++23) |
Verwendung
Der Gleitkomma-Umwandlungsrang und Unterrang werden ebenfalls verwendet, um
- bestimmen, ob eine Konvertierung zwischen verschiedenen Gleitkommatypen implizit erfolgen kann oder eine einschränkende Konvertierung ist,
- die Konvertierungssequenzen unterscheiden bei Überladenauflösung,
|
(seit C++23) |
- bestimmen, ob std::complex 's converting constructor explicit ist, oder
- bestimmen des gemeinsamen Gleitkommatyps, wenn Argumente verschiedener Gleitkommatypen an common oder special math functions übergeben werden.
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| CWG 1642 | C++98 | übliche arithmetische Konvertierungen könnten Lvalues betreffen | wendet Lvalue-zu-Rvalue-Konvertierungen zuerst an |
| CWG 2528 | C++20 |
der Drei-Wege-Vergleich zwischen
unsigned
char
und unsigned int ist aufgrund der intermediären integralen Promotion ungültig [1] |
bestimmt den gemeinsamen Typ basierend
auf den promovierten Typen, ohne tatsächlich die Operanden zu promoten [2] |
| CWG 2892 | C++98 |
wenn beide Operanden denselben
Gleitkommatyp haben, war die Bedeutung von "keine weitere Konvertierung erforderlich" unklar |
geändert in "keine weitere
Konvertierung wird durchgeführt" |
- ↑ Vor der Lösung wurde unsigned char zu Beginn von Phase 5 zu int heraufgestuft, dann wurde es zu unsigned int konvertiert. Allerdings ist die letztere Konvertierung einschränkend, was den Drei-Wege-Vergleich fehlerhaft macht.
- ↑ Nach der Lösung ist der gemeinsame Typ weiterhin unsigned int . Der Unterschied besteht darin, dass unsigned char direkt zu unsigned int konvertiert wird, ohne die Zwischenstufe der integralen Heraufstufung. Die Konvertierung ist nicht einschränkend und daher ist der Drei-Wege-Vergleich wohlgeformt.