¿Es bueno hacer varios cast de tipos?, Se que es recomendable pero no lo se hasta que punto.
por ejemplo:
list.h
Código
typedef enum { LIST_CMP_EQUAL = 0x0, LIST_CMP_LESS_THAT = 1, LIST_CMP_GREATER_THAT = -1 } list_cmp_t; typedef enum { LIST_SORT_ASC, LIST_SORT_DESC } list_sort_t; typedef void* list_t; typedef list_t* list_ptr_t; typedef intptr_t list_value_t; typedef list_value_t* list_value_ptr_t; typedef list_value_ptr_t list_item_t; typedef list_item_t* list_item_ptr_t; typedef size_t list_size_t; typedef list_size_t* list_size_ptr_t; /** Definición de Callback que se encarga de crear un duplicado del list_value_t indicado en parámetro value. * @param value: list_value_t que se duplicara. * @return Retorna el elemento list_value_t duplicado del parámetro value. */ typedef list_value_t(*list_callback_clone_item)(const list_value_t value); /** Definicion de Callback que se encarga de destruir la memoria asignada al list_value_t. * @param value: list_value_t que se liberara. */ typedef void(*list_callback_release_item)(const list_value_t value); /** Definicion de CALLBACK que se encarga comparar dos list_value_t. * @param value1: list_value_t que se comparara con value2. * @param value2: list_value_t que se comparara con value1. * @return Retorna el resultado de la comparación. * AVL_CMP_LESS_THAT: Si value1 < value2. * AVL_CMP_EQUAL: Si value1 == value2. * AVL_CMP_GREATER_THAT: Si value1 > value2. */ typedef list_cmp_t(*list_callback_compare_item)(const list_value_t value1, const list_value_t value2); /** Crea una nueva lista de elementos list_value_t. * @param clone_item: Apuntador a la función CALLBACK que retornara la copia del valor a asignar. * @param release_item: Apuntador a la función CALLBACK que liberara la copia del valor duplicado en el list_callback_clone_item. * @param clone_item: Apuntador a un proceso CALLBACK que se encarga de comparar los list_item_t. * @return Retorna la nueva cola de datos queue_t que debera ser destruida con list_release(). */ list_t list_allocator(list_callback_clone_item clone_item, list_callback_release_item release_item, list_callback_compare_item compare_item);
Código
/** Tipo de dato list_data_t **/ typedef struct list_data list_data_t; /** Tipo de dato list_data_ptr_t **/ typedef list_data_t* list_data_ptr_t; /** Tipo de dato list_data_t **/ typedef struct list_item_data list_item_data_t; /** Tipo de dato list_data_ptr_t **/ typedef list_item_data_t* list_item_data_ptr_t; struct list_item_data { list_value_t value; /** Valor del item actual. **/ list_item_data_ptr_t prev; /** Apuntador al item derecho. **/ list_item_data_ptr_t next; /** Apuntador al item izquierdo. **/ list_data_ptr_t list; /** Apuntador a los datos generales de la lista. **/ }; /** Estructura que guarda la información generalizada de una lista de datos **/ struct list_data { list_item_data_ptr_t first; /** Primer elemento agregado a la lista **/ list_item_data_ptr_t last; /** Ultimo elemento agregado a la lista **/ list_size_t size; /** Cantidad de elementos **/ list_callback_clone_item clone_item; /** Apuntador a la función CALLBACK que retornara la copia del valor a asignar **/ list_callback_release_item release_item; /** Apuntador a la función CALLBACK que liberara la copia del valor duplicado en el list_callback_allocator **/ list_callback_compare_item compare_item; /** Apuntador a la función CALLBACK que compara dos elementos de la lista **/ }; ... list_item_t list_begin(list_t list) { if (list_empty(list)) return NULL; return (list_item_t)(((list_data_ptr_t)list)->first); }
Tambien en casos donde provienen de un puntero X y se quiere convertir a un int32_t
Código
/** Tipo de dato para la estructura AVL **/ typedef void* avl_t; typedef avl_t* avl_ptr_t; /** Tipo del dato que guarda el valor de un nodo **/ typedef uintptr_t avl_value_t; typedef avl_value_t* avl_value_ptr_t; typedef size_t avl_size_t; typedef avl_size_t* avl_size_ptr_t; /** Funcion que retorna el elemento menor de un elemento avl. * @param value: Nodo del arbol AVL anteriormente creado con avl_allocator(), sirve como pivote. * @return * NULl: No existe o hubo un error. */ avl_value_ptr_t avl_getlower(const avl_value_ptr_t value); /** * Funcion que busca un elemento (avl_value_t) en un elemento avl (avl_t) * @param avl: Arbol AVL anteriormente creado con avl_allocator(). * @param value: Elemento a buscar. * @return Retorna el apuntador al valor guardado. * NULL: No existe el valor buscado. **/ avl_value_ptr_t avl_find(avl_t avl, const avl_value_t value); /** Funcion que extrae un nodo del elemento avl indicado. * @param avl: Apuntador a una variable tipo avl_t anteriormente creada con avl_allocator(). * @param value: Elemento que se buscara. * @return * true: Si se extrajo del elemento avl * false: No se extrajo ya que no se encontro o el elemento avl esta vacio o se paso un parametro NULL. */ bool avl_remove(avl_t avl, const avl_value_ptr_t value); avl_value_ptr_t avl_getroot(const avl_t avl); ... while (!avl_empty(avl)) { //Comprobamos la integridad de eliminación con estas dos lineas. avl_value_t elim = (avl_value_t)randomnumber(*avl_getlower(avl_getroot(avl)), *avl_getupper(avl_getroot(avl))); avl_remove(avl, avl_find(avl, elim)); } long min(uint32_t a, uint32_t b) { return (a<b) ? a:b; } void swap(int32_t *a, int32_t *b) { *a ^= *b; *b ^= *a; *a ^= *b; } inline int randomnumber(int32_t lower, int32_t upper) { if (min(lower, upper) != lower) { swap(&lower, &upper); } }
Uso los list_t como sinónimo de un tipo void* que apunta a una estructura list_data_t, es decir list_t = void* = list_data_ptr_t esto lo hago debido a que estoy creando varias bibliotecas donde las estructuras están dentro de los archivos .c (algunas) y creando varias funciones para el trato de las mismas... aun estoy espesando a creer que esto es una idiotes pero este no es el punto.
El problema radica al momento de compilar con -std=c99 -ansi -wall -pedantic -pedantic-errors
me salta:
Código:
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|123|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘avl_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|130|error: el paso del argumento 1 de ‘randomnumber’ crea un entero desde un puntero sin una conversión|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|17|nota: se esperaba ‘int32_t’ pero el argumento es de tipo ‘avl_t’|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|130|error: el paso del argumento 2 de ‘randomnumber’ crea un entero desde un puntero sin una conversión|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|17|nota: se esperaba ‘int32_t’ pero el argumento es de tipo ‘avl_t’|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|144|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘avl_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|147|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘avl_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|160|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘avl_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|173|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘avl_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|189|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘avl_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|192|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘avl_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|228|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘map_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|248|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘map_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|251|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘map_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|264|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘map_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|276|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘map_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|291|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘map_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|293|aviso: formato ‘%d’ espera un argumento de tipo ‘int’, pero el argumento 2 es de tipo ‘map_size_t’ [-Wformat]|
/home/blackzerox/Documentos/Programacion/C/CScript/main.c|112|aviso: variable ‘value’ sin usar [-Wunused-variable]|
||=== Build finished: 19 errors, 0 warnings ===|
Pero claro compilando con -w se arregla todo y compila perfectamente, esto es un problema que apenas vengo captando y solucionando con varios cast pero lo veo muy, no encuentro palabras para esto solo no me agrada.
Código
-------------- Build: Debug in CCScript_Linux --------------- Compiling: main.c Compiling: src/CSAVL.c Compiling: src/CSArray.c Compiling: src/CSBlockmem.c Compiling: src/CSByte.c Compiling: src/CSInfija2PreFija.c Compiling: src/CSList.c Compiling: src/CSMap.c Compiling: src/CSQueue.c Compiling: src/CSStack.c Compiling: src/CSString.c Compiling: src/CSUtiles.c Compiling: src/CSVector.c Compiling: src/CScript.c Linking console executable: bin/Debug/CCScript_Linux Output size is 30,17 KB Process terminated with status 0 (0 minutes, 2 seconds) 0 errors, 0 warnings
- ¿En que momentos en necesario realmente usar los cast?.
- ¿Que tan bueno es usar typedef y en que casos (ademas de simplificar)?.
- ¿Es indispensable forzar C99 con -std=c99 -ansi -wall -pedantic -pedantic-errors y por ende obligar los cast?.
Dulces Lunas!¡.