template - void pointer c
Casting punteros vacĂos (4)
He visto muchos de los siguientes en el código C más antiguo:
type_t *x = (type_t *) malloc(...);
¿Para qué sirve lanzar el puntero desde malloc()
ya que es void *
? ¿Es porque los compiladores de C más antiguos no son compatibles con los punteros de vacíos y malloc()
utiliza para devolver char *
¿Para qué sirve lanzar el puntero desde malloc () ya que es nulo *?
Muy por el contrario. Debe lanzar un puntero de vacío a un tipo real antes de poder usarlo, porque un void *
no significa nada sobre los datos almacenados en esa ubicación.
El problema aquí no es la compatibilidad con ningún dialecto de C. El problema es C ++ . En C ++, un puntero vacío no se puede convertir automáticamente a ningún otro tipo de puntero. Entonces, sin una conversión explícita, este código no se compilaría con un compilador de C ++.
No soy consciente de que Malloc alguna vez devolvió un char *.
Pero la conversión implícita de void * a type_t * (o cualquier otro tipo) no siempre se ha permitido. Por lo tanto, la necesidad de convertir explícitamente al tipo adecuado.
Tu propia explicación es la correcta. Pre-ANSI C (''K&R'' C) no tenía un tipo void *
con conversión implícita. char *
duplicó como un tipo pseudo void *
, pero necesitaba la conversión explícita de un tipo de conversión.
En la C moderna, el reparto está mal visto porque puede suprimir las advertencias del compilador para un prototipo faltante de malloc
. En C ++, se necesita el casting (pero la mayoría de las veces deberías usar new
lugar de malloc
).
Actualizar
Mis comentarios a continuación que intentan explicar por qué se requiere el reparto no estaban claros, intentaré explicarlo mejor aquí. Podría pensar que incluso cuando malloc
devuelve char *
, el reparto no es necesario porque es similar a:
int *a;
char *b = a;
Pero en este ejemplo también se necesita un elenco. La segunda línea es una violación de restricción para el operador de asignación simple (C99 6.5.1.6.1). Ambos operandos de puntero deben ser de tipo compatible. Cuando cambias esto a:
int *a;
char *b = (char *) a;
la violación de la restricción desaparece (ambos operandos ahora tienen el tipo char *
) y el resultado está bien definido (para convertirlo en un puntero char). En la ''situación inversa'':
char *c;
int *d = (int *) c;
el mismo argumento se mantiene para la conversión, pero cuando int *
tiene requisitos de alineación más estrictos que char *
, el resultado es la implementación definida .
Conclusión: En los días previos a ANSI, el tipo de conversión fue necesario porque malloc
devolvió el char *
y no los resultados de conversión es una infracción de restricción para el operador ''=''.