Okuduğum çeşitli mesajları üzerinde yığın taşması RE: derefercing tip punned işaretçi hatası. Anladığım kadarıyla, hata aslında bir nesneye farklı tipte bir işaretçi (bir istisna yapılmış gibi gözükse de char*
) üzerinden erişilme tehlikesinin anlaşılabilir ve makul bir uyarı olduğu uyarısıdır.
Benim sorum aşağıdaki koda özgüdür: neden bir işaretçi adresi void**
bu uyarı için bir kalifiye (hata yoluyla terfi) için döküm -Werror
?
Dahası, bu kod, yalnızca biri uyarı / hata oluşturan birden fazla hedef mimarisi için derlenmiştir - bu, yasal olarak derleyici sürümüne özgü bir eksiklik anlamına gelebilir mi?
// 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;
}
Yukarıda belirtilen anlayışım doğruysa, a void**
, sadece bir işaretçi olarak, bu güvenli bir döküm olmalıdır.
Bu derleyiciye özgü uyarıyı / hatayı pasifize edecek lvalues kullanmayan bir geçici çözüm var mı ? Yani anlıyorum ve neden bu sorunu çözecektir, ancak freeFunc()
NULL amaçlanan bir arg-arg yararlanmak istiyorum çünkü bu yaklaşımdan kaçınmak istiyorum :
void* tmp = f;
freeFunc( &tmp );
f = NULL;
Problem derleyici (bir tanesinden):
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$
Şikayet etmeyen derleyici (çok sayıda):
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$
Güncelleme: Uyarının özellikle derlendiğinde oluşturulduğunu fark ettim -O2
(yalnızca belirtilen "sorun derleyicisiyle")
void**
, hala sadece bir işaretçi olarak, bu güvenli bir döküm olmalıdır." Vay be atla! Bazı temel varsayımlarınız var gibi görünüyor. Baytlar ve kaldıraçlar açısından daha az ve soyutlamalar açısından daha fazla düşünmeye çalışın, çünkü aslında programladığınız şey budur