Usual arithmetic conversions
De nombreux opérateurs binaires qui attendent des opérandes de type arithmétique ou énumération provoquent des conversions et produisent des types de résultat de manière similaire. L'objectif est d'obtenir un type commun, qui est également le type du résultat. Ce modèle est appelé les conversions arithmétiques usuelles .
Table des matières |
Définition
Les conversions arithmétiques habituelles sont définies comme suit :
Étape 1
Applique la conversion lvalue-vers-rvalue aux deux opérandes, les prvalues résultantes sont utilisées à la place des opérandes originales pour le processus restant.
Étape 2
|
(depuis C++11) |
Étape 3
|
(depuis C++26) |
Étape 4
- Si l'un des opérandes est de type à virgule flottante , les règles suivantes sont appliquées :
-
- Si les deux opérandes ont le même type, aucune conversion supplémentaire n'est effectuée.
- Sinon, si l'un des opérandes est d'un type non flottant, cet opérande est converti vers le type de l'autre opérande.
- Sinon, si les rangs de conversion en virgule flottante des types des opérandes sont ordonnés mais (depuis C++23) non égaux, alors l'opérande du type avec le rang de conversion en virgule flottante inférieur est converti vers le type de l'autre opérande.
|
(depuis C++23) |
- Sinon, les deux opérandes sont de types entiers, passez à l'étape suivante.
Étape 5
Les deux opérandes sont convertis en un type commun
C
. Étant donné les types
T1
et
T2
comme type promu (
selon les règles de promotion intégrale
) des opérandes, les règles suivantes sont appliquées pour déterminer
C
:
-
Si
T1etT2sont du même type,Cest ce type. -
Sinon, si
T1etT2sont tous deux des types entiers signés ou tous deux des types entiers non signés,Cest le type ayant le plus grand rang de conversion entière . -
Sinon, un type entre
T1etT2est un type entier signéS, l'autre type est un type entier non signéU. Appliquer les règles suivantes :
-
-
Si le rang de conversion entier de
Uest supérieur ou égal au rang de conversion entier deS,CestU. -
Sinon, si
Speut représenter toutes les valeurs deU,CestS. -
Sinon,
Cest le type entier non signé correspondant àS.
-
Si le rang de conversion entier de
|
Si un opérande est de type énumération et l'autre opérande est d'un type d'énumération différent ou d'un type à virgule flottante, ce comportement est déprécié. |
(depuis C++20)
(jusqu'à C++26) |
Rang de conversion des entiers
Chaque type entier possède un rang de conversion entier défini comme suit :
- Aucun deux types entiers signés autres que char et signed char (si char est signé) n'ont le même rang, même s'ils ont la même représentation.
- Le rang d'un type entier signé est supérieur au rang de tout type entier signé ayant une largeur inférieure.
- Les rangs des types entiers suivants diminuent dans l'ordre :
|
(depuis C++11) |
-
- long
- int
- short
- signed char
- Le rang de tout type entier non signé est égal au rang du type entier signé correspondant.
|
(depuis C++11) |
- Le rang de bool est inférieur au rang de tous les types entiers standards.
- Les rangs des types de caractères d'encodage ( char , char8_t (depuis C++20) , char16_t , char32_t , (depuis C++11) et wchar_t ) sont égaux aux rangs de leurs types sous-jacents , ce qui signifie :
-
- Le rang de char est égal au rang de signed char et unsigned char .
|
(depuis C++20) |
|
(depuis C++11) |
-
- Le rang de wchar_t est égal au rang de son type sous-jacent défini par l'implémentation.
|
(depuis C++11) |
-
Pour tous les types entiers
T1,T2, etT3, siT1a un rang supérieur àT2etT2a un rang supérieur àT3, alorsT1a un rang supérieur àT3.
Le rang de conversion entier est également utilisé dans la définition de la promotion intégrale .
Rang et sous-rang de conversion en virgule flottante
Rang de conversion en virgule flottante
Chaque type à virgule flottante possède un rang de conversion à virgule flottante défini comme suit :
-
Les rangs des types à virgule flottante standard diminuent dans l'ordre :
- long double
- double
- float
|
(depuis C++23) |
Sous-rang de conversion en virgule flottanteLes types en virgule flottante ayant un rang de conversion égal sont ordonnés par le sous-rang de conversion en virgule flottante . Le sous-rang forme un ordre total parmi les types ayant des rangs égaux.
Les types
|
(depuis C++23) |
Utilisation
Le rang de conversion en virgule flottante et le sous-rang sont également utilisés pour
- déterminer si une conversion entre différents types à virgule flottante peut être implicite ou constitue une conversion rétrécissante ,
- distinguer les séquences de conversion dans la résolution de surcharge,
|
(depuis C++23) |
- déterminer si std::complex 's constructeur de conversion est explicite, ou
- déterminer le type à virgule flottante commun si des arguments de types à virgule flottante différents sont passés aux fonctions mathématiques communes ou spéciales .
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement tel que publié | Comportement correct |
|---|---|---|---|
| CWG 1642 | C++98 | les conversions arithmétiques habituelles pouvaient impliquer des lvalues | applique d'abord les conversions lvalue-vers-rvalue |
| CWG 2528 | C++20 |
la comparaison à trois voies entre
unsigned
char
et unsigned int est mal formée en raison de la promotion intégrale intermédiaire [1] |
détermine le type commun basé
sur les types promus, sans promouvoir réellement les opérandes [2] |
| CWG 2892 | C++98 |
lorsque les deux opérandes sont du même
type à virgule flottante, la signification de « aucune conversion supplémentaire n'est nécessaire » n'était pas claire |
modifié en « aucune conversion
supplémentaire ne sera effectuée » |
- ↑ Avant la résolution, unsigned char est promu en int au début de l'étape 5, puis il est converti en unsigned int . Cependant, cette dernière conversion est rétrécissante, ce qui rend la comparaison à trois voies mal formée.
- ↑ Après la résolution, le type commun reste unsigned int . La différence est que unsigned char est directement converti en unsigned int sans la promotion intégrale intermédiaire. La conversion n'est pas rétrécissante et donc la comparaison à trois voies est bien formée.