2009-09-05 18 views
25

¿Cuál es el equivalente en C para el reinterpret_cast de C++?¿Cuál es el equivalente en C para reinterpret_cast?

+20

Tenga en cuenta que el equivalente '(tipo) exression' de C puede hacer mucho más que' reinterpret_cast' en C++ (bueno, después de todo, son dos idiomas diferentes, así que no podemos esperar mucho de todos modos). Puede convertir tipos enteros y de coma flotante entre sí. No concluya a partir de las respuestas que '(tipo) expresión' en C++ es equivalente a un' reinterpret_cast'. –

+0

@litb Este es un comentario interesante. Comprobé el código de ensamblaje producido por VC2008 y omite el mismo código. Estoy seguro de que esto no es suficiente, pero estoy realmente interesado en saber más sobre cuándo difiere? – AraK

+0

Casos diferentes de error de tiempo de compilación y comportamiento indefinido: 'int a = reinterpret_cast ('a');' (error de compilación). 'struct A {int a; }; struct B {int b; }; estructura C: A, B {int c; }; int main() {C c; B & b = reinterpretar_castición (c); b.b = 1; } '(comportamiento indefinido: observe la diferencia cuando cambie a' (B &) c': si el subobjeto B se almacena en un desplazamiento '! = 0x0', entonces' reinterpret_cast' no es necesario para preocuparse por los ajustes necesarios , mientras que un molde de estilo C lo hará. –

Respuesta

22
int *foo; 
float *bar; 

// c++ style: 
foo = reinterpret_cast< int * >(bar); 

// c style: 
foo = (int *)(bar); 
+4

Tenga en cuenta también el muy buen punto de litb en los comentarios a la pregunta original. – Crashworks

4

C-estilo escayolas acaba de ver como nombres de tipos entre paréntesis:

void *p = NULL; 
int i = (int)p; // now i is most likely 0 

Obviamente hay mejores usos para los moldes que esto, pero esa es la sintaxis básica.

+1

¿Por qué? ? ¿Cuál sería la excepción aquí? – bzeaman

1

Una conversión de estilo C es:

int* two = ...; 
pointerToOne* one = (pointerToOne*)two; 
+0

no debería ser que '==' sea un solo '=' '? – KPexEA

+0

Ambas son declaraciones válidas, y ambas se compilarán solo por el reparto. Por supuesto, si quiere que suceda algo además de la compilación, usaría '=' – MSalters

0

Puede emitir libremente los tipos de puntero en C como lo haría con cualquier otro tipo.

para ser completa:

void *foo; 
some_custom_t *bar; 
other_custom_t *baz; 
/* Initialization... */ 
foo = (void *)bar; 
bar = (some_custom_t *)baz; 
baz = (other_custom_t *)foo; 
+4

. Puede lanzar cualquier tipo de contenido, puede que no haga lo que espera, y no se garantiza que haga nada. –

2

No existe, porque reinterpret_cast no puede cambiar [constness] [3]. Por ejemplo,

int main() 
{ 
    const unsigned int d = 5; 
    int *g=reinterpret_cast< int* >(&d); 
    (void)g; 
} 

producirá el error:

dk.cpp: In function 'int main()':
dk.cpp:5:41: error: reinterpret_cast from type 'const unsigned int*' to type 'int*' casts away qualifiers

1

Si usted puede tomar la dirección del valor, una forma es convertir un puntero a ella a un puntero a un tipo diferente, y luego desreferencia el puntero.

Por ejemplo, una conversión por flotación a int:

int main() 
{ 
    float f = 1.0f; 

    printf ("f is %f\n", f); 
    printf ("(int) f is %d\n", (int)f); 
    printf ("f as an unsigned int:%x\n", *(unsigned int *)&f); 
} 

Salida:

f is 1.000000 
(int) f is 1 
f as an unsigned int:3f800000 

cuenta que este es probablemente no garantiza que funcione por la norma C. No se puede usar reinterpret_cast para enviar de float a int de todos modos, pero sería similar para un tipo que era compatible (por ejemplo, entre diferentes tipos de puntero).

Vamos a confirmar que el resultado anterior tiene sentido, de todos modos.

http://en.wikipedia.org/wiki/Single_precision_floating-point_format#IEEE_754_single-precision_binary_floating-point_format:_binary32

La última respuesta en binario:

Esta norma IEEE-754 formato de coma flotante: un bit de signo de 0, seguido de un 8 -bit exponente (011 1111 1), seguido de una mantisa de 23 bits (todos ceros).

Para interpretar el exponente, restar 127: 01111111b = 127, y 127 - 127 = 0. El exponente es 0.

para interpretar la mantisa, escribir después de 1 seguido de un punto decimal: 1,00000000000000000000000 (23 ceros). Esto es 1 en decimal.

Por lo tanto, el valor representado por hex 3f800000 es 1 * 2^0 = 1, como esperábamos.

0

¿Qué pasa con un operador de REINTERPRET para C:

#define REINTERPRET(new_type, var) (* ((new_type *) & var)) 

No me gusta decir "reinterpret_cast", porque elenco medios de conversión (en C), mientras que reinterpretar significa lo contrario: no hay conversión.

+2

¿Por qué alguien debería hacer esto? Es engañoso. No hagas tu código no provocado más complejo. –

Cuestiones relacionadas