Revisando el código fuente de la implementación del compilador de Ruby (así, por aprender) he visto algo en C que no había visto nunca (di que tampoco es que tenga mucha experiencia en C) y es la diferencia entre la declaración de parámetros entre ANSI C (C89) e ISO C (C99):
#include <stdio.h>
// compila con cualquier tipo de parámetros en la llamada (ANSI C)
int
testFunction1(parm1,parm2)
int parm1;
int parm2;
{
printf(“1. Funciona? parm1 = %d, parm2 = %d\n”,parm1,parm2);
printf(“1. En serio? parm1 = %s, parm2 = %d\n”,parm1,parm2);
return 0;
}
// compila pero sólo se le pueden pasar parámetros de tipo entero (ISO C)
int
testFunction2(int param1,int param2) {
printf(“2. Functiona? param1 = %d, param2 = %d\n”,param1,param2);
return 0;
}
int
main(void) {
printf(” -> testFunction1()\n”);
// funciona con cualquier tipo de parámetros (ANSI C)
testFunction1(“vida”,42);
printf(” <- testFunction1\n”);
// funciona sólo con enteros, con otro tipo no compila (ISO C)
printf(” -> testFunction2()\n”);
testFunction2(‘vida’,42);
printf(” <- testFunction2\n”);
return 0;
}
Con la primera forma, el tipo de los parámetros fuera de la declaración de la función, cuando se llamada a dicha función se le le puede parasar cualquier tipo de parámetros e, internamente, los convertirá al tipo declarado posteriormente aunque, como se puede ver en el segundo printf, dependiendo de si le pasas un %d o un %s, imprimirá una cosa u otra aunque su tipo sea distinto.
En la segunda forma, es el propio compilador el que muestra un error cuando pasas un parámetro que no coincide con el tipo declarado.
La salida es más o menos la siguiente (se puede ver que nuestro parámetro, aunque posteriormente declarado como int, también contiene la cadena vida):
-> testFunction1()
1. Funciona? parm1 = 134514096, parm2 = 42
1. En serio? parm1 = vida, parm2 = 42
<- testFunction1
-> testFunction2()
2. Funciona? param1 = 1986618465, param2 = 42
<- testFunction2
Para que esto compile también hay un pequeño truco y es que la palabra «vida» como primer parámetro de la segunda función va entre comillas simples, esto es, en lugar de tomarse como una cadena (char[] para ser exactos) se toma como un caracter (char), sí, como un caracter de 32 bits en lugar de 8 (es una palabra con 4 letras, un byte por letra). Por supuesto, con el correspondiente warning, pero compila.
Y aunque esto teóricamente es del C antiguo, viene muy bien para pasar cualquier tipo de parámetro a una función en lugar del famoso void*. El problema es saber, dentro de la función, qué es lo que llega.
No se si esta anotación es útil, pero al menos es curioso. El saber nunca está demás.






