Usual arithmetic conversions
Muchos operadores binarios que esperan operandos de tipo aritmético o enumeración provocan conversiones y producen tipos de resultado de manera similar. El propósito es producir un tipo común, que también es el tipo del resultado. Este patrón se denomina conversiones aritméticas usuales .
Contenidos |
Definición
Las conversiones aritméticas usuales se definen de la siguiente manera:
Etapa 1
Aplica lvalue-to-rvalue conversion a ambos operandos, los prvalues resultantes se utilizan en lugar de los operandos originales para el proceso restante.
Etapa 2
|
(desde C++11) |
Etapa 3
|
(desde C++26) |
Etapa 4
- Si alguno de los operandos es de tipo floating-point , se aplican las siguientes reglas:
-
- Si ambos operandos tienen el mismo tipo, no se realizará ninguna conversión adicional.
- De lo contrario, si uno de los operandos es de un tipo no de punto flotante, ese operando se convierte al tipo del otro operando.
- De lo contrario, si los rangos de conversión de punto flotante de los tipos de los operandos están ordenados pero (since C++23) no son iguales, entonces el operando del tipo con el menor rango de conversión de punto flotante se convierte al tipo del otro operando.
|
(desde C++23) |
- De lo contrario, si ambos operandos son de tipos enteros, proceda a la siguiente etapa.
Etapa 5
Ambos operandos se convierten a un tipo común
C
. Dados los tipos
T1
y
T2
como el tipo promovido (
bajo las reglas de promociones integrales
) de los operandos, se aplican las siguientes reglas para determinar
C
:
-
Si
T1yT2son del mismo tipo,Ces ese tipo. -
De lo contrario, si
T1yT2son ambos tipos enteros con signo o ambos tipos enteros sin signo,Ces el tipo con mayor rango de conversión entera . -
De lo contrario, un tipo entre
T1yT2es un tipo entero con signoS, el otro tipo es un tipo entero sin signoU. Aplicar las siguientes reglas:
-
-
Si el rango de conversión entera de
Ues mayor o igual que el rango de conversión entera deS,CesU. -
En caso contrario, si
Spuede representar todos los valores deU,CesS. -
En caso contrario,
Ces el tipo entero sin signo correspondiente aS.
-
Si el rango de conversión entera de
|
Si un operando es de tipo enumeración y el otro operando es de un tipo de enumeración diferente o un tipo de punto flotante, este comportamiento está obsoleto. |
(since C++20)
(until C++26) |
Rango de conversión de enteros
Cada tipo entero tiene un rango de conversión entera definido de la siguiente manera:
- Ningún otro par de tipos enteros con signo, aparte de char y signed char (si char tiene signo), tiene el mismo rango, incluso si tienen la misma representación.
- El rango de un tipo entero con signo es mayor que el rango de cualquier tipo entero con signo con un ancho menor.
- Los rangos de los siguientes tipos enteros disminuyen en orden:
|
(desde C++11) |
-
- long
- int
- short
- signed char
- El rango de cualquier tipo entero sin signo es igual al rango del tipo entero con signo correspondiente.
|
(since C++11) |
- El rango de bool es menor que el rango de todos los tipos enteros estándar.
- Los rangos de los tipos de caracteres de codificación ( char , char8_t (desde C++20) , char16_t , char32_t , (desde C++11) y wchar_t ) son iguales a los rangos de sus tipos subyacentes , lo que significa:
-
- El rango de char es igual al rango de signed char y unsigned char .
|
(desde C++20) |
|
(desde C++11) |
-
- El rango de wchar_t es igual al rango de su tipo subyacente definido por la implementación.
|
(desde C++11) |
-
Para todos los tipos enteros
T1,T2, yT3, siT1tiene mayor rango queT2yT2tiene mayor rango queT3, entoncesT1tiene mayor rango queT3.
El rango de conversión entera también se utiliza en la definición de integral promotion .
Rango y subrango de conversión de punto flotante
Rango de conversión de punto flotante
Cada tipo de punto flotante tiene un rango de conversión de punto flotante definido como sigue:
-
Los rangos de los tipos de punto flotante estándar disminuyen en orden:
- long double
- double
- float
|
(desde C++23) |
Subrango de conversión de punto flotanteLos tipos de punto flotante que tienen igual rango de conversión de punto flotante se ordenan mediante el subrango de conversión de punto flotante . El subrango forma un orden total entre tipos con rangos iguales.
Los tipos
|
(desde C++23) |
Uso
El rango de conversión de punto flotante y el subrango también se utilizan para
- determinar si una conversión entre diferentes tipos de punto flotante puede ser implícita o es una conversión de estrechamiento ,
- distinguir las secuencias de conversión en la resolución de sobrecarga,
|
(desde C++23) |
- determinar si el std::complex constructor de conversión es explícito, o
- determinar el tipo de punto flotante común si se pasan argumentos de diferentes tipos de punto flotante a las funciones matemáticas comunes o especiales .
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| CWG 1642 | C++98 | las conversiones aritméticas usuales podían involucrar lvalues | aplica primero las conversiones lvalue-to-rvalue |
| CWG 2528 | C++20 |
la comparación de tres vías entre
unsigned
char
y unsigned int estaba mal formada debido a la promoción integral intermedia [1] |
determina el tipo común basándose
en los tipos promocionados, sin promover realmente los operandos [2] |
| CWG 2892 | C++98 |
cuando ambos operandos son del mismo
tipo de punto flotante, el significado de "no se necesita más conversión" no estaba claro |
cambiado a "no se realizará
más conversión" |
- ↑ Antes de la resolución, unsigned char se promueve a int al inicio de la etapa 5, luego se convierte a unsigned int . Sin embargo, esta última conversión es restrictiva, lo que hace que la comparación de tres vías sea incorrecta.
- ↑ Después de la resolución, el tipo común sigue siendo unsigned int . La diferencia es que unsigned char se convierte directamente a unsigned int sin la promoción integral intermedia. La conversión no es restrictiva y por lo tanto la comparación de tres vías es correcta.