J'ai lu divers articles sur Stack Overflow RE: l'erreur de pointeur punencé par déréférencement. Ma compréhension est que l'erreur est essentiellement l'avertissement du compilateur du danger d'accéder à un objet via un pointeur d'un type différent (bien qu'une exception semble être faite pour char*
), ce qui est un avertissement compréhensible et raisonnable.
Ma question est spécifique au code ci-dessous: pourquoi la conversion de l'adresse d'un pointeur en un void**
qualifie-t-elle pour cet avertissement (promu en erreur via -Werror
)?
De plus, ce code est compilé pour plusieurs architectures cibles, dont une seule génère l'avertissement / l'erreur - cela peut-il impliquer qu'il s'agit légitimement d'une déficience spécifique à la version du compilateur?
// 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 ma compréhension, énoncée ci-dessus, est correcte, a void**
, n'étant encore qu'un pointeur, cela devrait être un casting sûr.
Existe-t-il une solution de contournement n'utilisant pas les valeurs l qui pacifierait cet avertissement / erreur spécifique au compilateur? C'est-à-dire que je comprends cela et pourquoi cela résoudra le problème, mais je voudrais éviter cette approche parce que je veux profiter de freeFunc()
NULL ing un out-arg prévu:
void* tmp = f;
freeFunc( &tmp );
f = NULL;
Compilateur de problèmes (l'un parmi les autres):
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$
Compilateur non conforme (l'un des nombreux):
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$
Mise à jour: j'ai en outre découvert que l'avertissement semble être généré spécifiquement lors de la compilation avec -O2
(toujours avec le "compilateur de problèmes" noté uniquement)
void**
, n'étant toujours qu'un pointeur, ce devrait être un casting sûr." Woah là skippy! On dirait que vous avez des hypothèses fondamentales en cours. Essayez de penser moins en termes d'octets et de leviers et plus en termes d'abstractions, car c'est ce que vous programmez avec