Funcion en C

Zyd
25 de Junio del 2005
Viendo un prorgama me he encontrado con dos funciones de las cuales no puedo entender bien su construccion, alguna ayuda que me aclare....

static size_t read_alias_file PARAMS ((const char *fname, int fname_len))internal_function;


(struct alias_map *) bsearch (&item, map, nmap,
sizeof (struct alias_map),
(int (*) PARAMS ((const void *,
const void *))
) alias_compare);

Definiciones que se usan en las funciones:

static int alias_compare PARAMS ((const struct alias_map *map1,
const struct alias_map *map2));

#ifndef internal_function
# define internal_function
#endif

quisiera saber en general como esta constituida pero en particular
size_t lo habia visto en los prototipos de funciones de biblioteca, pero nunca en una funcion en si, para que se utiliza?

static size_t read_alias_file PARAMS ((const char *fname, int fname_len))internal_function;

Hay varias funciones declaradas como la anterior, que uso tiene PARAMS?
Que uso tiene la macro que esta despues del cierre de parametros (internal_function)

static size_t internal_function read_alias_file (fname, fname_len) const char *fname; int fname_len;

Este es la forma que tiene la funcion cuando se esta definiendo su cuerpo, por que el cambio respecto a su declaracion? el doble parentesis en los paramtros de la declaracion de la funcion afecta en algo?

hiei
25 de Junio del 2005
El parametro size_t es un tipo de dato definido "por el usuario" (bueno, por los fabricantes de la libreria estandar del C que usa tu compilador) y es una abstraccion para determinar eso, un tipo tamaño (size type). El tipo, realmente seria un int o un long dependiendo del compilador, sistema operativo, y plataforma que uses (oviamente, es para abstraer al programador de estas cosas.

La macro internal_function es propia del compilador y (oviamente como especifica el define que anda por ahi) solo es un espacio en blanco (por lo menos si no se define algun otro atributo (muy comun en los compiladores basados en GCC que pueden contener la directiva __atrivute__ (...) que les permite determinar la seccion del codigo objeto, el runlevel de ejecucin de ese codigo, las propiedades de lectura y escritura sobre esa seccion de codigo y otras osas mas...) Simple compatibilidad hacia atras o acia adelante para mejoras en el codigo (supongo que mas de una funcion estara marcada con internal_function...

La macro PARAMS (que por cierto es algo tambien particular del compilador o las librerias que usas) tambien existe para asistir en la portabilidad y lo unico que hace (aparentemente) es dar un marco mas automatico en la declaracion de parametros , porque en el formato Kernigan& Richers los parametros no se declaraban como en ANSI C:
Declaracion ANSI C:
int main( int argc, char **argv);
Declaracion K&R:
int main (argc, argv) /* si, el tipo vien, saludos... no se savia para nada... */
Entonces lo que intentaria esta macro es, segun el tipo de compilacion que se este usando, acomodar la declaracion de los parametros en funcionde si es ANSI C o K&R.
Esto queda eidenciado en la declaracion que se ve mas abajo:
static size_t read_alias_file (fname, fname_len) const char *fname; int fname_len;
Obie el internal_function pues no hace nada (paarentemente en tu caso)

La sencencia:
(struct alias_map *) bsearch (&item, map, nmap,
sizeof (struct alias_map),
(int (*) PARAMS ((const void *,
const void *))
) alias_compare);
Llama a la fuincion bsearch cuyo prototipo deve ser:
void * bsearch(void *key, void *base, size_t n, size_t z,
int (*compare) (void *, void *));
Lo que tiene esa llamada es que se han hecho todas las comverciones de tipo (typecast) adecuadamente (las explicitas y las implicitas) como deve ser en un buen codigo generico que usa punteros a void*

Para mas informacion sobre la funcion bsearch y sus parametros en (la original de BSD 4.4):
http://www.hmug.org/man/3/bsearch.php

Realmente, ese tipo de declaraciones no son estandares al C y no deverias de prestarle atencion a menso que te dediques a modificar las librerias estandares (y no tanto) o a hacer las tuyas propias.
Si quieres ver ekl codigo real que generan estas macros pasalo por el preprocesador (generalmente CPP) y a su salida veras el codigo con todos los macros reemplazados como realmente los ve el compilador.
Si dije algo que no quedo claro, pregunten de nuevo por favor.