cast operator
Realiza conversión explícita de tipo
Contenidos |
Sintaxis
(
nombre-de-tipo
)
expresión
|
|||||||||
donde
| type-name | - | ya sea el tipo void o cualquier tipo escalar |
| expression | - | cualquier expresión de tipo escalar (a menos que type-name sea void , en cuyo caso puede ser cualquier cosa) |
Explicación
Si type-name es void , entonces expression se evalúa por sus efectos secundarios y su valor devuelto se descarta, igual que cuando expression se utiliza por sí sola, como una expresión de sentencia .
De lo contrario, si type-name es exactamente el tipo de expression , no se hace nada (excepto que si expression tiene tipo flotante y se representa con mayor rango y precisión de lo que indica su tipo – véase más abajo).
De lo contrario, el valor de la expression se convierte al tipo especificado por type-name , de la siguiente manera:
Toda conversión implícita como si fuera por asignación está permitida.
Además de las conversiones implícitas, se permiten las siguientes conversiones:
- Cualquier entero puede convertirse a cualquier tipo de puntero. Excepto para las constantes de puntero nulo como NULL (que no requiere conversión ), el resultado está definido por la implementación, puede no estar correctamente alineado, puede no apuntar a un objeto del tipo referenciado, y puede ser una representación trampa .
- Cualquier tipo de puntero puede convertirse a cualquier tipo entero. El resultado está definido por la implementación, incluso para valores de puntero nulo (no necesariamente resultan en el valor cero). Si el resultado no puede representarse en el tipo destino, el comportamiento es indefinido (los enteros sin signo no implementan aritmética modular en una conversión desde puntero).
- Cualquier puntero a objeto puede convertirse a cualquier otro puntero a objeto. Si el valor no está correctamente alineado para el tipo destino, el comportamiento es indefinido. De lo contrario, si el valor se convierte de vuelta al tipo original, se compara igual al valor original. Si un puntero a objeto se convierte a puntero a cualquier tipo carácter, el resultado apunta al byte más bajo del objeto y puede incrementarse hasta el tamaño del tipo destino (en otras palabras, puede usarse para examinar la representación de objeto o para hacer una copia mediante memcpy o memmove ).
- Cualquier puntero a función puede convertirse a un puntero a cualquier otro tipo de función. Si el puntero resultante se convierte de vuelta al tipo original, se compara igual al valor original. Si el puntero convertido se usa para realizar una llamada a función, el comportamiento es indefinido (a menos que los tipos de función sean compatibles ).
- Al convertir entre punteros (ya sea de objeto o función), si el valor original es un valor de puntero nulo de su tipo, el resultado es el valor correcto de puntero nulo para el tipo destino.
En cualquier caso (tanto al ejecutar una conversión implícita como en el cast del mismo tipo), si expression y type-name son tipos flotantes y expression se representa con mayor rango y precisión de lo que indica su tipo (ver FLT_EVAL_METHOD ), el rango y la precisión se eliminan para coincidir con el tipo destino.
La categoría de valor de la expresión de conversión siempre es no-lvalue.
Notas
Debido a que los calificadores
const
,
volatile
,
restrict
, y
_Atomic
tienen efecto únicamente en
lvalues
, una conversión a un tipo calificado cvr o atómico es exactamente equivalente a la conversión al tipo no calificado correspondiente.
La conversión a void es a veces útil para silenciar advertencias del compilador sobre resultados no utilizados.
Las conversiones no listadas aquí no están permitidas. En particular,
- no hay conversiones entre punteros y tipos de coma flotante;
- no hay conversiones entre punteros a funciones y punteros a objetos (incluyendo void * ).
|
Si la implementación proporciona intptr_t y/o uintptr_t , entonces una conversión de un puntero a un tipo de objeto (incluyendo cv void ) a estos tipos siempre está bien definida. Sin embargo, esto no está garantizado para un puntero a función. |
(desde C99) |
Tenga en cuenta que las conversiones entre punteros a función y punteros a objeto son aceptadas como extensiones por muchos compiladores, y son necesarias para algunos usos de la función POSIX
dlsym
.
Ejemplo
#include <stdio.h> int main(void) { // examinar la representación de objetos es un uso legítimo del cast const double d = 3.14; printf("El double %.2f (%a) es: ", d, d); for (size_t n = 0; n != sizeof d; ++n) printf("%02X ", ((unsigned char*)&d)[n]); // casos límite struct S { int x; } s; // (struct S)s; // error; no es un tipo escalar, aunque // convertir al mismo tipo no hace nada (void)s; // es válido convertir cualquier tipo a void }
Salida:
El double 3.14 (0x1.91eb851eb851fp+1) es: 1F 85 EB 51 B8 1E 09 40
Referencias
- Estándar C23 (ISO/IEC 9899:2024):
-
- 6.5.5 Operadores de conversión (p: 83-84)
- Estándar C17 (ISO/IEC 9899:2018):
-
- 6.5.4 Operadores de conversión (p: 65-66)
- Estándar C11 (ISO/IEC 9899:2011):
-
- 6.5.4 Operadores de conversión (p: 91)
- Estándar C99 (ISO/IEC 9899:1999):
-
- 6.5.4 Operadores de conversión (p: 81)
- Estándar C89/C90 (ISO/IEC 9899:1990):
-
- 3.3.4 Operadores de conversión
Véase también
|
Documentación de C++
para
conversión explícita de tipos
|