Conversión implícita de tipos

La conversión de tipos se produce automáticamente si se utiliza un tipo en algún punto del código fuente pero se espera otro, y existen reglas de conversión entre ellos. Dicha conversión se denomina conversión de tipo implícita y puede que no siempre se corresponda con la intención del programador. Además, algunas operaciones de conversión tienen efectos secundarios, y el compilador, al no saber si su uso es intencionado, resalta las líneas de código correspondientes con avisos. Para resolver estos problemas existe una sintaxis de conversión de tipos explícita (véase Reparto de tipos explícita).

Ya hemos visto varias reglas para la conversión implícita de tipos al estudiar los tipos y variables.

En concreto, si se asigna un valor de un tipo distinto a booleano a una variable bool , el valor 0 se considera false y todos los demás, true. En el caso más general, todas las expresiones que dan por sentada la presencia de condiciones lógicas se convierten al tipo bool. Por ejemplo, el primer operando de un operador condicional ternario siempre se convierte en bool.

Pero si un valor de tipo bool se asigna a un tipo numérico, entonces true se convierte en 1 y false, en 0.

Cuando se asigna un número real a una variable de tipo entero, la parte fraccionaria se descarta (el compilador emite un aviso). En cambio, cuando se asigna un número entero a una variable de tipo real, se puede perder precisión (el compilador también emite un aviso). Ya hemos hablado de ello en las secciones sobre Números enteros y Números reales.

Si tenemos números enteros y de punto flotante, todo se convierte a números de punto flotante del tamaño máximo utilizado (normalmente double,, a menos que se especifique de forma explícita float o que el literal numérico tenga un sufijo 'f', como por ejemplo1234.56789f).

Para los enteros de diferentes tamaños también existen reglas de conversión: se expanden si es necesario, lo que significa que aumentan hasta el tamaño del tipo entero más grande utilizado en la expresión (véase Conversiones aritméticas de tipo).

Además de las expresiones, a menudo necesitamos convertir tipos de forma implícita durante la inicialización y la asignación, cuando los tipos a la derecha y a la izquierda del signo '=' no coinciden. Se aplican las mismas reglas de conversión cuando se pasan valores a través de parámetros de funciones y cuando se devuelven resultados de funciones (para obtener más detalles, consulte la sección Funciones).

Teniendo en cuenta lo anterior se puede realizar un gran número de conversiones en una sola línea de código. Si esto da lugar a avisos del compilador, es una buena idea asegurarse de que la conversión es intencionada y eliminar dichos avisos insertando una conversión de tipo explícita.

short s = 10;
long n = 10;
int p = s * n + 1.0;

En este ejemplo, al realizar una multiplicación, el tipo de la variable s se extiende al tipo del segundo operando long y se obtiene un resultado intermedio del tipo long. Como la constante 1.0 es del tipo double, el resultado del producto se convierte a double antes de la suma. El resultado global también es del tipo double; sin embargo, la variable p es del tipo int y, por lo tanto, se realiza una conversión implícita de double a int.

Los tipos especiales datetime y color se procesan según las reglas de los enteros con longitudes de 8 y 4 bytes, respectivamente. Pero para la fecha y la hora hay un límite más estricto en cuanto al valor máximo: se trata de 32535244799, que corresponde a D'3000,12.31 23:59:59'.

La mayoría de los tipos pueden convertirse de forma implícita a y desde cadenas, pero los resultados no siempre son adecuados, por lo que el compilador emite avisos «conversión implícita de 'número' a 'cadena'» y «conversión implícita de 'cadena' a 'número'» para que el programador pueda comprobarlas. Por ejemplo, convertir una cadena en un número entero permite que la cadena sólo contenga dígitos y caracteres '+'/'-' al principio. La conversión de una cadena a un número real permite, además de los números, la presencia de un punto '.' y la notación con «exponente» ('e' o 'E', por ejemplo +1,2345e-1). Si en la cadena se encuentra un carácter no admitido (por ejemplo, una letra), el resto de la cadena se descarta por completo.

Por ejemplo, la cadena de fecha y hora («2021,12.12 00:00») no puede asignarse sin pérdidas a una variable de tipo datetime porque datetime es un número entero (número de segundos). En este caso, la lectura del número de la cadena finalizará cuando se alcance el primer punto, es decir, el número obtendrá el valor 2021. Este número de segundos se corresponde con el minuto 34 del año 1970.

Existen funciones especiales para este tipo de conversiones (véase la sección Transformación de datos).

La única dirección de conversión de tipos implícita y explícita que está prohibida es de string a bool. En estos casos, el compilador muestra el mensaje de error «no se puede convertir de forma implícita el tipo 'cadena' a 'bool'».

Encontrará ejemplos de este capítulo en TypeConversion.mq5.