Estoy escribiendo una función donde me gustaría aceptar 2 types de parámetros.
- A
string(char *) - A
structuredonde habrá n número de elementos.
Y para lograr esto, estoy pensando en usar un tipo simple void *como parámetro. Pero no sé cómo verificar si el parámetro es de un tipo u otro, de forma segura.

void*apuntan.func_strefunc_structy recibir cheques de tipo en tiempo de compilación._Genericmacro. También podría crear tipos autoidentificables, por ejemplo, con uniones etiquetadas , lo que significaría que no puede pasar unachar *cadena sin procesar . Todo eso es probablemente más problemas de lo que vale.Respuestas:
La traducción de
void*es"Estimado compilador, este es un puntero, y no hay información adicional para usted sobre esto".
Por lo general, el compilador sabe mejor que usted (el programador), debido a la información que obtuvo antes y que aún recuerda y que quizás haya olvidado.
Pero en este caso especial, usted sabe mejor o necesita saber mejor. En todos los casos,
void*la información está disponible de otra manera, pero solo para el programador, que "sabe". El programador debe proporcionar la información al compilador, o mejor al programa en ejecución, porque la única ventaja quevoid*tiene es que la información puede cambiar durante el tiempo de ejecución.Por lo general, esto se realiza al proporcionar la información a través de parámetros adicionales a las funciones, a veces a través del contexto, es decir, el programa "sabe" (por ejemplo, para cada tipo posible hay una función separada, la función que se llame implica el tipo).
Entonces, al final
void*no contiene la información de tipo.Muchos programadores malinterpretan esto como "No necesito saber la información de tipo".
Pero lo contrario es cierto, el uso de
void*aumenta la responsabilidad del programador para realizar un seguimiento de la información de tipo y proporcionarla de manera adecuada al programa / compilador.fuente
void*función, convierte al tipo incorrecto, luego des-referencia los datos ... entonces se invoca todo tipo de comportamiento indefinido.void*están en desuso para la programación genérica, no hay muchas situaciones en las que deba usarlas hoy en día. Son peligrosos porque conducen a una seguridad de tipo inexistente. Y como notó, también pierde la información de tipo, lo que significa que tendría que arrastrar algo engorrosoenumjunto con elvoid*.En su lugar, debe usar C11,
_Genericque puede verificar los tipos en tiempo de compilación y agregar seguridad de tipo. Ejemplo:Recuerde proporcionar
constversiones calificadas ( ) de todos los tipos que desea admitir.Si desea mejores errores de compilación cuando la persona que llama pasa el tipo incorrecto, puede agregar una afirmación estática:
Si intenta algo así
int x; func(x);, recibirá el mensaje del compilador"x: incorrect type".fuente