Stack Overflow REのさまざまな 投稿 を 読みました:逆参照型でパンされたポインターエラーです。私の理解では、エラーは本質的に、異なる型のポインターを介してオブジェクトにアクセスする危険性についてのコンパイラー警告である(例外はに対して行われているように見えます)と理解でき、これは理解できる合理的な警告です。char*
私の質問は以下のコードに固有です:なぜポインターのアドレスvoid**
をこの警告の修飾にキャストするの-Werror
ですか(を介してエラーにプロモートされます)?
さらに、このコードは複数のターゲットアーキテクチャ用にコンパイルされており、そのうちの1つだけが警告/エラーを生成します。これは、正当にコンパイラのバージョン固有の欠陥であることを意味しているのでしょうか?
// 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;
}
上記の私の理解が正しければ、はvoid**
単なるポインタであり、これは安全にキャストできるはずです。
このコンパイラ固有の警告/エラーを緩和するlvalueを使用しない回避策はありますか?つまり、私はそれが問題を解決する理由と理由を理解していfreeFunc()
ますが、意図した出力引数のNULLを利用したいので、このアプローチは避けたいと思います。
void* tmp = f;
freeFunc( &tmp );
f = NULL;
問題のコンパイラ(1つのうちの1つ):
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$
不満のないコンパイラ(多くの1つ):
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$
更新:さらに、コンパイル時に特に警告が生成されるように見えることを発見しました-O2
(まだ「問題のあるコンパイラ」のみが記載されています)
void**
まだ、単なるポインタなので、これは安全にキャストできるはずです。」スキッ!あなたはいくつかの基本的な仮定が続いているように思えます。バイトとレバーの観点ではなく、抽象化の観点から考えるようにしてください。それは、実際にプログラミングしているものだからです