2015-09-23 17 views
6

gcc 5.2.0 का उपयोग के साथ शून्य लौटने, मैंने देखा है कि इस कोड को एक चेतावनी उत्पन्न नहीं करता है:कोई चेतावनी जब जीसीसी

#include <stddef.h> 

int function(void) 
{ 
    return NULL; 
} 

void procedure(void) 
{ 
    return NULL; 
} 

मैं झंडे -Wall -Wextra -std=c99 -pedantic का इस्तेमाल किया और मैं archlinux चल रहा हूँ। मुझे यकीन नहीं है कि यह कोड gcc पर ठीक क्यों काम करता है, खासकर clang 3.7.0 एक चेतावनी उत्पन्न करता है।

मैंने gcc के पुराने संस्करणों के साथ 4.9 या 4.7 की तरह भी कोशिश की और वे दोनों चेतावनियां उत्पन्न करते हैं।

चेतावनी है:

warning: return makes integer from pointer without a cast 

और

warning: ‘return’ with a value, in function returning void 

मुझे लगता है कि मैं डेबियन पर जीसीसी 5.2 संकलन की कोशिश की और परिणाम एक ही है उल्लेख करना चाहिए। तो archlinux समस्या प्रतीत नहीं होता है।

तर्क क्या है? मुझे कहीं और इससे संबंधित कुछ भी नहीं मिल रहा है।

धन्यवाद!

+1

संभावित डुप्लिकेट http://stackoverflow.com/questions/1610030/why-can-you-return-from-a-non-void-function-without-returning-a-value-without-pr –

+0

लॉल आपका मतलब है "उलटा डुप्लिकेट"? यह सवाल पूछता है कि आप एक शून्य कार्य के शरीर में मूल्य क्यों वापस कर सकते हैं। "डुप्लिकेट" पूछता है कि आप रिटर्न स्टेटमेंट के बिना गैर-शून्य कार्य का एक शरीर क्यों लिख सकते हैं। – BitTickler

+0

संभावित डुप्लिकेट [क्यों एक फंक्शन से 0x80000000 वापस नहीं लौटाता है जो int32 \ _t चेतावनी देता है?] (Http://stackoverflow.com/questions/32656460/why-doesnt-returning-0x80000000-from-a- कार्यक्षमता -थैट-रिटर्न-इंट 32-टी-कारण-ए-वा) –

उत्तर

1

मैं यहाँ एक बग रिपोर्ट भरा: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67730

यह पुष्टि की गई और 5.3 ऐसा लगता है के लिए तय हो गई है!

आपकी मदद के लिए धन्यवाद।

1

पहले फ़ंक्शन की वैधता इस बात पर निर्भर करती है कि NULL कैसे परिभाषित किया गया है। NULL को 0 के रूप में परिभाषित किया गया है, तो पहले फ़ंक्शन के साथ कोई समस्या नहीं है। लेकिन अगर इसे (void *) 0 (जो आमतौर पर सी कोड में मामला है) के रूप में परिभाषित किया जाता है तो पहला कार्य अमान्य हो जाता है। जीसीसी अक्सर निहित सूचक-से-पूर्णांक रूपांतरणों के बारे में बहुत अनुमोदित है।

दूसरा फ़ंक्शन अमान्य है। भाषा विनिर्देश स्पष्ट रूप से बताता है कि "अभिव्यक्ति के साथ एक रिटर्न स्टेटमेंट किसी फ़ंक्शन में दिखाई नहीं देगा जिसका रिटर्न टाइप शून्य है।" यदि यह संकलित करता है, तो यह किसी अन्य चीज़ के बारे में अत्यधिक अनुमोदित होने का जीसीसी का एक और उदाहरण होना चाहिए।

यदि आप इसके डायग्नोस्टिक आउटपुट मानक सी भाषा से संबंधित होना चाहते हैं तो आपको -pedantic मोड में जीसीसी चलाने की आवश्यकता है। डिफ़ॉल्ट मोड में यह एक विश्वसनीय सी संकलक नहीं है (कम से कम इसके नैदानिक ​​आउटपुट के थर्म में) और तथ्य यह है कि यह "चेतावनी जारी नहीं करता है" का अर्थ बिल्कुल कुछ भी नहीं है।

फिर भी मेरे प्रयोगों में मैं जीसीसी को दूसरे कार्य के बारे में शिकायत करने में सक्षम नहीं था, यहां तक ​​कि -std= और -pedantic स्विच के साथ भी। यह कंपाइलर में एक बग की तरह दिखता है।

+0

ओपी '-pedantic' का उपयोग करने का दावा करता है। – juanchopanza

+0

मैं वास्तव में '-pedantic' का उपयोग कर रहा हूं। – damwdan

3

यह जीसीसी 5.2.0 में एक प्रतिगमन प्रतीत होता है - और, जहां तक ​​मैं कह सकता हूं, एक अजीब व्यक्ति।

जीसीसी 4.4.5 और 4.8.4 के साथ, कार्यक्रम (आवश्यक #include <stddef.h> जोड़ने के बाद) return NULL; कथन दोनों पर चेतावनियां उत्पन्न करता है, यहां तक ​​कि बिना किसी अतिरिक्त कमांड लाइन विकल्प के।

जीसीसी 5.2.0 के साथ, कोई चेतावनी उत्पादन किया जाता है, यहां तक ​​कि gcc -c -Wall -Wextra -std=c99 -pedantic साथ। दूसरे के लिए, जो void फ़ंक्शन से मान देता है, एक निदान अनिवार्य है।

अब यहां अजीब हिस्सा है।

$ gcc --version | head -n 1 
gcc (GCC) 5.2.0 
$ cat c.c 
#include <stddef.h> 

int function(void) { 
#ifdef USE_NULL 
    return NULL; 
#else 
    return ((void*)0); 
#endif 
} 

void procedure(void) { 
#ifdef USE_NULL 
    return NULL; 
#else 
    return ((void*)0); 
#endif 
} 
$ gcc -c c.c 
c.c: In function ‘function’: 
c.c:7:12: warning: return makes integer from pointer without a cast [-Wint-conversion] 
    return ((void*)0); 
      ^
c.c: In function ‘procedure’: 
c.c:15:12: warning: ‘return’ with a value, in function returning void 
    return ((void*)0); 
      ^
$ gcc -c -DUSE_NULL c.c 
$ 

जब USE_NULL परिभाषित किया गया है, कोई चेतावनी नहीं दी जाती है।gcc -E -DUSE_NULL के साथ संकलन (जो प्रीप्रोसेसर के आउटपुट को stdout पर प्रिंट करता है) पुष्टि करता है कि NULL को ((void*)0) के रूप में परिभाषित किया गया है। लेकिन जब मैं NULL को ((void*)0) के साथ प्रतिस्थापित करता हूं, तो चेतावनियां उत्पन्न होती हैं (जैसा कि वे होना चाहिए)।

मुझे नहीं पता कि क्या हो रहा है। एक बार मैक्रो NULL का विस्तार हो जाने के बाद, इसे ((void*)0) से अलग करने योग्य होना चाहिए, और फिर भी इसका उपयोग करने के आधार पर संकलक का व्यवहार बदलता है।

+0

आप शायद 5.2.0 का मतलब है। –

+0

@ एंटोनीपेट्री: फिक्स्ड, धन्यवाद! –

संबंधित मुद्दे