Stack Overflow RE 에 대한 다양한 게시물 을 읽었습니다 : derefercing type-punned pointer error. 내 이해는 오류가 본질적으로 다른 유형의 포인터를 통해 객체에 액세스 할 위험에 대한 컴파일러 경고라는 것입니다 (예외가 있지만 ) 이해할 수 있고 합리적인 경고입니다.char*
내 질문은 아래 코드와 관련이 있습니다. 포인터 주소를 캐스팅 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**하고 여전히 포인터 인 경우 안전한 캐스팅이되어야합니다.
이 컴파일러 관련 경고 / 오류 를 완화 시키는 lvalue 를 사용하지 않는 해결 방법 이 있습니까? 즉, 이것이 문제를 해결하는 이유를 이해하지만 의도 된 out-arg 를 freeFunc() NULL로 사용 하고 싶기 때문에이 접근법을 피하고 싶습니다 .
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(여전히 "문제가있는 컴파일러"만 있음)
void**아직도 그냥 포인터이기 때문에 안전한 캐스팅이되어야합니다." 우와 저기! 근본적인 가정이 진행되고있는 것 같습니다. 즉 당신이 실제로 프로그래밍을하는지 때문에, 바이트 레버의 측면에서 더 추상화의 측면에서 덜 생각하려고