Ho letto vari post su Stack Overflow RE: l'errore del puntatore tipo-derefercing puntato. La mia comprensione è che l'errore è essenzialmente l'avvertimento del compilatore del pericolo di accedere a un oggetto attraverso un puntatore di tipo diverso (sebbene un'eccezione sembri essere fatta per char*
), che è un avvertimento comprensibile e ragionevole.
La mia domanda è specifica per il codice seguente: perché il casting dell'indirizzo di un puntatore si void**
qualifica per questo avviso (promosso a errore tramite -Werror
)?
Inoltre, questo codice viene compilato per più architetture di destinazione, solo una delle quali genera l'avviso / errore - ciò potrebbe implicare che si tratti legittimamente di un difetto specifico della versione del compilatore?
// 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;
}
Se la mia comprensione, dichiarata sopra, è corretta, a void**
, essendo ancora solo un puntatore, questo dovrebbe essere un casting sicuro.
Esiste una soluzione alternativa che non utilizza i valori che pacificherebbe questo avviso / errore specifico del compilatore? Vale a dire che lo capisco e perché questo risolverà il problema, ma vorrei evitare questo approccio perché voglio trarre vantaggio da freeFunc()
NULL ing out-arg previsto:
void* tmp = f;
freeFunc( &tmp );
f = NULL;
Compilatore di problemi (uno di 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$
Compilatore non lagnante (uno dei tanti):
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$
Aggiornamento: ho scoperto inoltre che l'avviso sembra essere generato specificamente quando compilato -O2
(sempre con il solo "compilatore di problemi")
void**
, essendo ancora solo un puntatore, questo dovrebbe essere un casting sicuro." Woah lì skippy! Sembra che tu abbia alcune assunzioni fondamentali in corso. Cerca di pensare meno in termini di byte e leve e di più in termini di astrazioni, perché questo è ciò con cui stai effettivamente programmando