[C con Clase] cast con punteros a funciones

Steven Davidson srd4121 en njit.edu
Jue Mayo 6 15:52:44 CEST 2010


Hola Matías,


2010/5/6 Matias V. <fockewulffw44j en gmail.com>

> Hola tengo la siguiente duda,
>
> Supongamos que tengo la siguiente funcion
>
> int prueba(void(*algo)(void*))
> {
>    int a=5;
>
>    (*algo)(&a);
>


Esto no es necesario en C/C++. Simplemente escribe:

algo( &a );



> }
>
> y por ejemplo esta otra
>
> void ejemplo(int * b)
> {
>     printf ("%i",*b);
> }
>
> en el main invoco a prueba haciendo un cast:
>
> int main()
> {
>   prueba( (void(*)(void*))ejemplo);
> }
>
> lo que no entiendo es por que todo funciona correctamente, es decir al
> hacer el cast el argumento de ejemplo  (de acuerdo a lo que tengo entendido)
> se convierte en un puntero void por lo cual el compilador me debería tirar
> error al intenetar imprimir el contenido de una varible apuntada por un
> puntero void, tal
>


Bueno, teóricamente, en este caso, no se convierte en 'void *', sino más
bien el argumento es tratado como si fuese de tipo 'void *'.



> como ocurre en este ejemplo.
>
> void funcion(void* asd)
> {
>    printf("%i",*asd)
>


Aquí sí tenemos un error porque intentas acceder al elemento apuntado por
'asd'. Sin embargo, el compilador no sabe cuántos bytes ocupa la información
ni tampoco cómo manipularla, por el mero hecho de que no sabe el tipo del
dato apuntado.

Si sólo manipulas los punteros y direcciones de memoria, entonces puedes
hacer cástings entre punteros: 'int *' a 'void *' y viceversa; 'float *' a
'void *' y viceversa; etcétera. En cuanto intentes acceder a la información
apuntada, entonces el compilador echa mano al tipo apuntado para determinar
cuántos bytes necesita leer o escribir.

Una posible solución para este error, es realizar un cásting a 'int *', para
poder acceder al número entero correctamente. Esto es,

 void funcion( void *asd )
{
   printf( "%i", *((int*)asd) );
}



> }
> int main()
> {
>    int a=5;
>    funcion(&a);
> }
>
>
>


En tu código original, no accedes al valor apuntado por el 'void *', sino al
número entero apuntado por 'int *' en la función 'ejemplo()'. Por esta
razón, no se produce ningún error.


Espero haber aclarado la duda.

Steven
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20100506/209f79a3/attachment.html>


Más información sobre la lista de distribución Cconclase