我已阅读various posts on Stack Overflow RE:取消引用类型标记的指针错误。我的理解是,该错误实质上是编译器警告,它警告通过不同类型的指针访问对象的危险(尽管char*
似乎有例外),这是可以理解且合理的警告。 / p>
我的问题特定于以下代码:为什么强制将指针的地址转换为void**
才能获得此警告(通过-Werror
导致错误)?
此外,此代码针对多个目标体系结构进行了编译,只有其中一种会生成警告/错误-这是否暗示它在合法上是特定于编译器版本的缺陷?
// 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**
仍然只是一个指针,这应该是安全的转换。
是否有一种解决方法不使用左值来解决此编译器特定的警告/错误?即我理解这以及为什么这可以解决问题,但是我想避免使用这种方法,因为我想利用freeFunc()
NULL 来使用预期的out-arg:
void* tmp = f;
freeFunc( &tmp );
f = NULL;
问题编译器(之一):
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$
不兼容的编译器(众多)之一:
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
编译时生成的(仍然仅使用指出的“问题编译器”)