He leído varias publicaciones en Stack Overflow RE: el error de puntero de tipo punteado de desreferencia. Entiendo que el error es esencialmente la advertencia del compilador del peligro de acceder a un objeto a través de un puntero de un tipo diferente (aunque parece haber una excepción char*
), que es una advertencia comprensible y razonable.
Mi pregunta es específica del código a continuación: ¿ por qué la conversión de la dirección de un puntero a una void**
calificación para esta advertencia (promovida a error a través de -Werror
)?
Además, este código se compila para múltiples arquitecturas de destino, solo una de las cuales genera la advertencia / error. ¿Podría esto implicar que es legítimamente una deficiencia específica de la versión del compilador?
// main.c
#include <stdlib.h>
typedef struct Foo
{
int i;
} Foo;
void freeFunc( void** obj )
{
if ( obj && * obj )
{
free( *obj );
*obj = NULL;
}
}
int main( int argc, char* argv[] )
{
Foo* f = calloc( 1, sizeof( Foo ) );
freeFunc( (void**)(&f) );
return 0;
}
Si mi entendimiento, indicado anteriormente, es correcto, un void**
, siendo solo un puntero, esto debería ser un casting seguro.
¿Hay alguna solución alternativa que no utilice valores que alivien esta advertencia / error específico del compilador? Es decir, entiendo eso y por qué esto resolverá el problema, pero me gustaría evitar este enfoque porque quiero aprovechar freeFunc()
NULL en un argumento fuera de discusión:
void* tmp = f;
freeFunc( &tmp );
f = NULL;
Compilador de problemas (uno de uno):
user@8d63f499ed92:/build$ /usr/local/crosstool/x86-fc3/bin/i686-fc3-linux-gnu-gcc --version && /usr/local/crosstool/x86-fc3/bin/i686-fc3-linux-gnu-gcc -Wall -O2 -Werror ./main.c
i686-fc3-linux-gnu-gcc (GCC) 3.4.5
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
./main.c: In function `main':
./main.c:21: warning: dereferencing type-punned pointer will break strict-aliasing rules
user@8d63f499ed92:/build$
Compilador que no se queja (uno de muchos):
user@8d63f499ed92:/build$ /usr/local/crosstool/x86-rh73/bin/i686-rh73-linux-gnu-gcc --version && /usr/local/crosstool/x86-rh73/bin/i686-rh73-linux-gnu-gcc -Wall -O2 -Werror ./main.c
i686-rh73-linux-gnu-gcc (GCC) 3.2.3
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
user@8d63f499ed92:/build$
Actualización: descubrí que la advertencia parece generarse específicamente cuando se compila -O2
(solo con el "compilador del problema")
void**
, siendo solo un puntero, esto debería ser un casting seguro". Woah hay skippy! Parece que tienes algunas suposiciones fundamentales. Trate de pensar menos en términos de bytes y palancas y más en términos de abstracciones, porque eso es con lo que realmente está programando