2011-07-04 16 views
6

Escribo un intérprete y me gustaría poder almacenar cualquier valor que una función devuelva en un puntero void. No he tenido problemas para almacenar entradas y varios punteros como punteros vacíos, pero aparece un error al intentar convertir un doble como un puntero de vacío. Entiendo que los dobles se almacenan de forma diferente que los enteros y punteros en el nivel de bits, pero no entiendo por qué no puedo colocar los bits que quiero en el puntero (asumiendo que tiene suficiente memoria asignada) y luego los saco más tarde, lanzándolos como un doble.Convirtiendo double to void * en C

¿Es posible convertir un doble en un puntero vacío utilizando una sintaxis que no conozco o no entiendo cómo funcionan los punteros vacíos?

+4

Ha considerado el uso de un 'union' en su lugar? –

+4

Parece que estás haciendo algo terriblemente incorrecto. Por favor mira la respuesta de David. – pmr

+0

verifique mi respuesta en esta otra pregunta http://stackoverflow.com/questions/6539023/storing-values-in-union-in-c/6539185#6539185 –

Respuesta

12

En muchos sistemas, un double tiene 8 bytes de ancho y un puntero de 4 bytes de ancho. El primero, por lo tanto, no encajaría en este último.

Parecería estar abusando de void*. Su solución implicará la asignación de espacio de almacenamiento al menos tan grande como el tipo más grande que necesita almacenar en alguna estructura similar a una variante, p. a union.

+2

No puedo creer que nunca haya oído hablar de un sindicato . Esto es exactamente lo que estaba buscando. – Jack

+1

+1 por sugerir el enfoque correcto. :) –

2

Por supuesto, es posible lanzarlo. Void Pointers es lo que hace que el polimorfismo sea posible en C. Necesitas saber de antemano lo que estás pasando a tu función.

void *p_v ; 
double *p_d ; 
p_d = malloc(sizeof(double)) ; 
p_v = (void *) p_d ; 
+0

Su ejemplo parece funcionar porque 'p_d' es un puntero. La operación estaba preguntando sobre una conversión de no-puntero a void *. –

0

Aquí es que

int main () { 
    double d = 1.00e+00 ; // 0x3ff0000000000000 
    double * pd = & d ; 
    void * * p = (void * *) pd ; 
    void * dp = * p ; 
    printf ("%f %p %p %p \n" , d , pd , p , dp) ; 
    return 0 ; 
} ; 

salida

1.000000 0x7fff89a7de80 0x7fff89a7de80 0x3ff0000000000000 

2ª y 3ª direcciones podrían ser diferentes. Un acceso directo

void * dp = * (void * *) & d ; 

Saludos

+0

Esto es un comportamiento indefinido (violación estricta de aliasing) –

+0

@ M.M no lo es. Estoy lanzando el puntero, sé lo que estoy haciendo, no es C++, compila y da el resultado correcto. No sugeriría usar una técnica de este tipo en un código largo, pero estoy en lo cierto. – Fabio

+0

La expresión '* p' tiene el tipo' void * 'pero está accediendo a la memoria que en realidad es de tipo' double * '. Esos incluso podrían ser de diferentes tamaños –