मैंने स्टैक ओवरफ्लो आरई पर विभिन्न पोस्ट पढ़ी हैं : डेरेफेरिंग टाइप-पेंडिंग पॉइंटर एरर। मेरी समझ यह है कि त्रुटि अनिवार्य रूप से एक अलग प्रकार के पॉइंटर के माध्यम से किसी वस्तु तक पहुंचने के खतरे की संकलक चेतावनी है (हालांकि एक अपवाद के लिए बनाया गया प्रतीत होता है ), जो एक समझ और उचित चेतावनी है। 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**
, अभी भी सिर्फ एक सूचक होने के नाते, यह सुरक्षित कास्टिंग होना चाहिए।
क्या इस संकलक-विशिष्ट चेतावनी / त्रुटि को शांत करने वाले अंतराल का उपयोग नहीं करने के लिए एक समाधान है ? यानी मैं समझता हूं कि यह क्यों और इस मुद्दे को हल करेगा, लेकिन मैं इस दृष्टिकोण से बचना चाहूंगा क्योंकि मैं 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**
, अभी भी एक संकेतक होने के नाते, यह सुरक्षित कास्टिंग होना चाहिए।" वाह वहाँ कंजूसी! लगता है जैसे आपके पास कुछ मौलिक धारणाएं हैं। बाइट्स और लीवर के संदर्भ में कम और अमूर्तता के संदर्भ में अधिक सोचने की कोशिश करें, क्योंकि यही आप वास्तव में प्रोग्रामिंग कर रहे हैं