Namespaces
Variants

Usual arithmetic conversions

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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

  • Wenn einer der Operanden vom Typ scoped enumeration ist, werden keine Konvertierungen durchgeführt; wenn der andere Operand nicht denselben Typ hat, ist der Ausdruck ungültig.
  • Andernfalls fahre mit der nächsten Stufe fort.
(since C++11)

Stufe 3

  • Wenn einer der Operanden vom Typ enumeration type ist und der andere Operand von einem anderen Enumerationstyp oder einem Gleitkommatyp ist, ist der Ausdruck ungültig.
  • Andernfalls fahren Sie mit der nächsten Stufe fort.
(since C++26)

Stufe 4

  • 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.
  • Andernfalls, wenn die Gleitkomma-Konvertierungsränge der Typen der Operanden gleich sind, dann wird der Operand mit dem geringeren Gleitkomma-Konvertierungsunterrang zum Typ des anderen Operanden konvertiert.
  • Andernfalls ist der Ausdruck fehlerhaft.
(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 T1 und T2 denselben Typ haben, ist C dieser Typ.
  • Andernfalls, wenn T1 und T2 beide vorzeichenbehaftete Ganzzahltypen oder beide vorzeichenlose Ganzzahltypen sind, ist C der Typ mit dem höheren Integer-Konvertierungsrang .
  • Andernfalls ist einer der Typen zwischen T1 und T2 ein vorzeichenbehafteter Ganzzahltyp S , der andere Typ ist ein vorzeichenloser Ganzzahltyp U . Wende die folgenden Regeln an:
  • Wenn der Integer-Konvertierungsrang von U größer oder gleich dem Integer-Konvertierungsrang von S ist, ist C gleich U .
  • Andernfalls, wenn S alle Werte von U darstellen kann, ist C gleich S .
  • Andernfalls ist C der vorzeichenlose Integer-Typ, der S entspricht.

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:
  • long long
(seit C++11)
  • long
  • int
  • short
  • signed char
  • Der Rang jedes vorzeichenlosen Ganzzahltyps entspricht dem Rang des entsprechenden vorzeichenbehafteten Ganzzahltyps.
  • Der Rang jedes Standard-Ganzzahltyps ist größer als der Rang jedes erweiterten Ganzzahltyps mit derselben Breite.
(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 .
  • Der Rang von char8_t entspricht dem Rang von unsigned char .
(seit C++20)
(seit C++11)
  • Der Rang von wchar_t entspricht dem Rang seines implementierungsdefinierten zugrundeliegenden Typs.
  • Der Rang eines beliebigen erweiterten vorzeichenbehafteten Ganzzahltyps relativ zu einem anderen erweiterten vorzeichenbehafteten Ganzzahltyp mit derselben Breite ist implementierungsdefiniert, unterliegt jedoch weiterhin den anderen Regeln zur Bestimmung des Integer-Konvertierungsrangs.
(since C++11)
  • Für alle ganzzahligen Typen T1 , T2 und T3 , wenn T1 einen höheren Rang als T2 hat und T2 einen höheren Rang als T3 hat, dann hat T1 einen höheren Rang als T3 .

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
  • Der Rang eines Gleitkommatyps T ist größer als der Rang jedes Gleitkommatyps, dessen Wertemenge eine echte Teilmenge der Wertemenge von T ist.
  • Zwei erweiterte Gleitkommatypen mit derselben Wertemenge haben gleiche Ränge.
  • Ein erweiterter Gleitkommatyp mit derselben Wertemenge wie genau ein cv-unqualifizierter Standard-Gleitkommatyp hat einen Rang gleich dem Rang dieses Standard-Gleitkommatyps.
  • Ein erweiterter Gleitkommatyp mit derselben Wertemenge wie mehr als ein cv-unqualifizierter Standard-Gleitkommatyp hat einen Rang gleich dem Rang von double .
(seit C++23)


Floating-Point-Konvertierungs-Subrang

Gleitkommatypen mit gleichem Gleitkomma-Konvertierungsrang werden nach ihrem Gleitkomma-Konvertierungs-Subrang geordnet. Der Subrang bildet eine Totalordnung zwischen Typen mit gleichem Rang.

Die Typen std::float16_t , std::float32_t , std::float64_t und std::float128_t ( Festbreiten-Gleitkommatypen ) haben einen höheren Konvertierungs-Subrang als jeder Standard-Gleitkommatyp mit gleichem Konvertierungsrang. Andernfalls ist die Reihenfolge des Konvertierungs-Subrangs implementierungsdefiniert.

(seit C++23)

Verwendung

Der Gleitkomma-Umwandlungsrang und Unterrang werden ebenfalls verwendet, um

(seit C++23)

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"
  1. 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.
  2. 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.