मान को वापस किए बिना गैर-शून्य फ़ंक्शन के अंत में बहने वाला संकलक त्रुटि क्यों नहीं उत्पन्न करता है?


158

जब से मुझे कई साल पहले एहसास हुआ, कि यह डिफ़ॉल्ट रूप से (जीसीसी में कम से कम) त्रुटि पैदा नहीं करता है, मैंने हमेशा सोचा है कि क्यों?

मैं समझता हूं कि आप चेतावनी देने के लिए संकलक झंडे जारी कर सकते हैं, लेकिन क्या यह हमेशा एक त्रुटि नहीं होनी चाहिए? एक गैर-शून्य फ़ंक्शन के लिए यह क्यों समझ में आता है कि मान मान्य नहीं है?

टिप्पणियों में अनुरोध किया गया एक उदाहरण:

#include <stdio.h>
int stringSize()
{
}

int main()
{
    char cstring[5];
    printf( "the last char is: %c\n", cstring[stringSize()-1] ); 
    return 0;
}

... संकलित करता है।


9
वैकल्पिक रूप से, मैं सभी चेतावनियों को हालांकि त्रुटियों की तरह तुच्छ मानता हूं, और मैं उन सभी चेतावनियों को सक्रिय करता हूं जो मैं कर सकता हूं (यदि आवश्यक हो तो स्थानीय निष्क्रियता के साथ ... लेकिन फिर यह कोड में स्पष्ट क्यों है)।
मैथ्यू एम।

8
-Werror=return-typeउस चेतावनी को त्रुटि के रूप में मानेंगे। मैंने सिर्फ चेतावनी को नजरअंदाज कर दिया और कुछ मिनटों की हताशा को ट्रैक करते हुए एक अमान्य thisसूचक ने मुझे यहां और इस निष्कर्ष पर पहुंचा दिया।
jozxyqk

यह इस तथ्य से भी बदतर बना दिया जाता है कि एक std::optionalसमारोह के अंत के बिना बहने वाला एक "सच्चा" वैकल्पिक रिटर्न देता है
रुफस

@ Rufus यह करने के लिए नहीं है। आपकी मशीन / कंपाइलर / OS / चंद्र चक्र पर ऐसा ही हुआ। अपरिभाषित व्यवहार के कारण जो भी संकलक कोड उत्पन्न होता है, वह सिर्फ एक 'सही' विकल्प की तरह दिखता है, जो कुछ भी हो।
अंडरस्कोर_ड

जवाबों:


146

C99 और C ++ मानकों को मान वापस करने के लिए फ़ंक्शन की आवश्यकता नहीं होती है। मान-लौटाने वाले फ़ंक्शन में अनुपलब्ध रिटर्न स्टेटमेंट को 0केवल mainफ़ंक्शन में (लौटने के लिए ) परिभाषित किया जाएगा ।

औचित्य में यह भी शामिल है कि यदि प्रत्येक कोड पथ का मान लौटाया जाए तो यह जाँचना काफी कठिन है, और एम्बेडेड असेंबलर या अन्य पेचीदा तरीकों से वापसी मूल्य निर्धारित किया जा सकता है।

से सी ++ 11 मसौदा:

2 6.6.3 / 2

एक समारोह के अंत में बहने [...] का परिणाम मान-लौटाने वाले फ़ंक्शन में अपरिभाषित व्यवहार होता है।

5 3.6.1 / 5

यदि नियंत्रण mainएक return बयान के सामना किए बिना अंत तक पहुंचता है , तो प्रभाव निष्पादन का है

return 0;

ध्यान दें कि C ++ 6.6.3 / 2 में वर्णित व्यवहार C में समान नहीं है।


यदि आप इसे कहते हैं तो gcc आपको चेतावनी देगा-ग्रेट-टाइप विकल्प।

जब भी किसी फ़ंक्शन को एक रिटर्न-प्रकार से परिभाषित किया जाता है, जो इंट-डिफॉल्ट के लिए परिभाषित होता है, तो वॉर्न-टाइप वार्न । किसी भी रिटर्न स्टेटमेंट के बारे में किसी फंक्शन में बिना रिटर्न-वैल्यू के साथ आगाह करें जिसका रिटर्न-टाइप शून्य नहीं है (फंक्शन बॉडी के अंत में गिरने को वैल्यू के बिना रिटर्निंग माना जाता है), और एक फंक्शन में एक एक्सप्रेशन के साथ रिटर्न स्टेटमेंट के बारे में जिसका वापसी प्रकार शून्य है।

यह चेतावनी -Wall द्वारा सक्षम है ।


जिज्ञासा के रूप में, यह कोड क्या करता है:

#include <iostream>

int foo() {
   int a = 5;
   int b = a + 1;
}

int main() { std::cout << foo() << std::endl; } // may print 6

इस कोड में औपचारिक रूप से अपरिभाषित व्यवहार है, और व्यवहार में यह कन्वेंशन और आर्किटेक्चर पर निर्भर है। एक विशेष सिस्टम पर, एक विशेष संकलक के साथ, रिटर्न वैल्यू अंतिम अभिव्यक्ति मूल्यांकन का परिणाम है, eaxजो उस सिस्टम के प्रोसेसर के रजिस्टर में संग्रहीत होता है ।


13
मैं अपरिभाषित व्यवहार को "अनुमत" कहने से सावधान रहूंगा, हालांकि माना जाता है कि मैं इसे "निषिद्ध" कहना गलत होगा। त्रुटि नहीं होना और निदान की आवश्यकता नहीं होना "अनुमति" के समान नहीं है। बहुत कम से कम, आपका जवाब थोड़ा सा पढ़ता है जैसे आप कह रहे हैं कि यह करना ठीक है, जो मोटे तौर पर ऐसा नहीं है।
ऑर्बिट

4
@ कैटस्कुल, आप उस तर्क को क्यों खरीदते हैं? क्या यह संभव नहीं होगा, यदि तुच्छ रूप से आसान नहीं है, तो किसी फ़ंक्शन के निकास बिंदुओं की पहचान करना और सुनिश्चित करें कि वे सभी एक मूल्य (और घोषित वापसी प्रकार का एक मूल्य) लौटाते हैं?
ब्लूबॉम्बर

3
@ कैटस्कुल, हाँ और नहीं। वैधानिक रूप से टाइप की गई और / या संकलित भाषाएं बहुत सारी चीजें करती हैं जिन्हें आप शायद "बेहद महंगा" मानते हैं, लेकिन क्योंकि वे केवल एक बार करते हैं, संकलन के समय, उनके पास नगण्य खर्च होता है। यहां तक ​​कि यह कहते हुए कि, मैं यह नहीं देखता कि किसी फ़ंक्शन के निकास बिंदुओं की पहचान करना सुपर-लीनियर होने की आवश्यकता क्यों है: आप केवल फ़ंक्शन के एएसटी को पीछे छोड़ते हैं और रिटर्न या निकास कॉल की तलाश करते हैं। यह रैखिक समय है, जो निश्चित रूप से कुशल है।
ब्लूबॉम्बर

3
@LightnessRacesinOrbit: एक वापसी मान वाला एक समारोह कभी कभी एक मूल्य के साथ तुरंत वापस आती है और कभी कभी एक और समारोह जो हमेशा के माध्यम से बाहर निकल जाता है कॉल करता है throwया longjmp, संकलक एक पहुँच योग्य नहीं किया जा सकेगा returnगैर लौटने कार्य करने के लिए आह्वान के बाद? जिस मामले में इसकी आवश्यकता नहीं है, वह बहुत आम नहीं है, और इसे ऐसे मामलों में भी शामिल करने की आवश्यकता शायद अति महत्वपूर्ण नहीं है, लेकिन आवश्यकता नहीं होने का निर्णय उचित है।
सुपरकाट

1
@ सुपरकैट: एक सुपर-बुद्धिमान कंपाइलर ऐसे मामले में चेतावनी या त्रुटि नहीं देगा, लेकिन - फिर से - यह सामान्य मामले के लिए अनिवार्य रूप से अयोग्य है, इसलिए आप अंगूठे के एक सामान्य नियम के साथ फंस गए हैं। यदि आप जानते हैं, हालांकि, कि आपका अंत-कार्य कभी नहीं पहुंचेगा, तो आप पारंपरिक समारोह के शब्दार्थ से इतनी दूर हैं कि हां, आप आगे बढ़ सकते हैं और ऐसा कर सकते हैं और जान सकते हैं कि यह सुरक्षित है। सच कहूँ तो, तुम उस बिंदु पर C ++ से नीचे की परत हो और, जैसे भी हो, इसकी सभी गारंटियाँ वैसे भी मूट हैं।
ऑर्बिट

42

gcc डिफ़ॉल्ट रूप से जाँच नहीं करता है कि सभी कोड पथ एक मान लौटाते हैं क्योंकि सामान्य रूप से ऐसा नहीं किया जा सकता है। यह मानता है कि आप जानते हैं कि आप क्या कर रहे हैं। गणना का उपयोग करते हुए एक सामान्य उदाहरण पर विचार करें:

Color getColor(Suit suit) {
    switch (suit) {
        case HEARTS: case DIAMONDS: return RED;
        case SPADES: case CLUBS:    return BLACK;
    }

    // Error, no return?
}

आप प्रोग्रामर जानते हैं कि, एक बग को छोड़कर, यह तरीका हमेशा एक रंग देता है। जीसीसी को भरोसा है कि आप जानते हैं कि आप क्या कर रहे हैं ताकि यह आपको फ़ंक्शन के निचले हिस्से में वापसी करने के लिए मजबूर न करे।

दूसरी ओर, javac, यह सत्यापित करने का प्रयास करता है कि सभी कोड पथ एक मान लौटाते हैं और एक त्रुटि फेंकता है यदि यह साबित नहीं कर सकता कि यह सब करते हैं। यह त्रुटि जावा भाषा विनिर्देश द्वारा अनिवार्य है। ध्यान दें कि कभी-कभी यह गलत है और आपको अनावश्यक रिटर्न स्टेटमेंट में डालना होगा।

char getChoice() {
    int ch = read();

    if (ch == -1 || ch == 'q') {
        System.exit(0);
    }
    else {
        return (char) ch;
    }

    // Cannot reach here, but still an error.
}

यह एक दार्शनिक अंतर है। C और C ++ जावा या C # की तुलना में अधिक अनुमेय और विश्वसनीय भाषा हैं और इसलिए नई भाषाओं में कुछ त्रुटियां C / C ++ में चेतावनी हैं और कुछ चेतावनियों को डिफ़ॉल्ट रूप से अनदेखा या बंद किया जाता है।


2
यदि javac वास्तव में कोड-रास्तों की जाँच करता है तो यह नहीं देखेगा कि आप उस बिंदु तक कभी नहीं पहुँच सकते?
क्रिस लुत्ज़

3
पहले एक में यह आपको एनम के सभी मामलों को कवर करने के लिए क्रेडिट नहीं देता है (आपको स्विच के बाद डिफ़ॉल्ट केस या रिटर्न की आवश्यकता होती है), और दूसरे में यह नहीं पता कि यह System.exit()कभी नहीं लौटता है।
जॉन कुगेलमैन

2
यह javac (अन्यथा शक्तिशाली संकलक) के लिए सीधा लगता है कि यह System.exit()कभी नहीं लौटता है। मैंने इसे देखा ( java.sun.com/j2se/1.4.2/docs/api/java/lang/… ), और डॉक्स सिर्फ इतना कहते हैं कि "सामान्य रूप से कभी नहीं लौटता"। मुझे आश्चर्य है कि इसका क्या अर्थ है ...
पॉल बिगगर

@Paul: इसका मतलब है कि उनके पास एक अच्छा विचारक नहीं था। अन्य सभी भाषाओं का कहना है कि "सामान्य रूप से कभी नहीं लौटता" - यानी, "सामान्य वापसी तंत्र का उपयोग करके वापस नहीं आता है।"
मैक्स लिबर्ट रॉबर्ट

1
मैं निश्चित रूप से एक संकलक को पसंद करूंगा जो कम से कम चेतावनी देता है अगर यह उस पहले उदाहरण का सामना करता है, क्योंकि तर्क की शुद्धता टूट जाती है अगर किसी ने एनम के लिए एक नया मूल्य जोड़ा। मैं एक डिफ़ॉल्ट मामला चाहता हूं जिसने जोर से शिकायत की और / या दुर्घटनाग्रस्त हो गया (शायद एक जोर का उपयोग करके)।
injektilo

14

आपका मतलब है, एक मूल्य-वापसी समारोह के अंत में बहना (यानी एक स्पष्ट रूप से बाहर निकलना return) एक त्रुटि नहीं है?

सबसे पहले, सी में एक फ़ंक्शन कुछ सार्थक लौटाता है या नहीं केवल महत्वपूर्ण है जब निष्पादन कोड वास्तव में लौटे मूल्य का उपयोग करता है। हो सकता है कि भाषा आपको कुछ भी वापस करने के लिए मजबूर नहीं करना चाहती थी जब आपको पता हो कि आप ज्यादातर समय वैसे भी इसका उपयोग नहीं करने जा रहे हैं।

दूसरे, स्पष्ट रूप से भाषा विनिर्देश संकलक लेखकों को एक स्पष्ट की उपस्थिति के लिए सभी संभावित नियंत्रण पथों का पता लगाने और सत्यापित करने के लिए मजबूर नहीं करना चाहते थे return(हालांकि कई मामलों में ऐसा करना मुश्किल नहीं है)। इसके अलावा, कुछ नियंत्रण पथ नॉन-रिटर्निंग फ़ंक्शंस में ले जा सकते हैं - वह गुण जो आमतौर पर संकलक के लिए ज्ञात नहीं है। इस तरह के रास्ते कष्टप्रद झूठी सकारात्मक का स्रोत बन सकते हैं।

ध्यान दें, कि C और C ++ इस मामले में व्यवहार की अपनी परिभाषा में भिन्न हैं। C ++ में केवल वैल्यू रिटर्निंग फ़ंक्शन के अंत में बहने वाला हमेशा अपरिभाषित व्यवहार होता है (कॉल कोड द्वारा फ़ंक्शन के परिणाम का उपयोग किया जाता है चाहे)। C में यह केवल अपरिभाषित व्यवहार का कारण बनता है यदि कॉलिंग कोड लौटाए गए मान का उपयोग करने का प्रयास करता है।


+1 लेकिन C ++ returnके अंत से पूर्व कथन नहीं छोड़ सकते main()?
क्रिस लुत्ज़

3
@ क्रिस लुत्ज़: हाँ, mainइस संबंध में विशेष है।
चींटी

5

सी / सी ++ के तहत यह कानूनी है कि किसी ऐसे फ़ंक्शन से वापस न आना जो कुछ वापस करने का दावा करता है। उपयोग के कई मामले हैं, जैसे कॉलिंग exit(-1), या एक फ़ंक्शन जो इसे कॉल करता है या एक अपवाद फेंकता है।

कंपाइलर कानूनी C ++ को अस्वीकार नहीं करने जा रहा है, भले ही वह यूबी की ओर जाता हो यदि आप इसे नहीं पूछ रहे हैं। विशेष रूप से, आप बिना किसी चेतावनी के उत्पन्न होने के लिए कह रहे हैं । (Gcc अभी भी कुछ डिफ़ॉल्ट रूप से चालू होता है, लेकिन जब उन्हें जोड़ा जाता है तो वे नई विशेषताओं के साथ संरेखित होते हैं, पुरानी विशेषताओं के लिए नई चेतावनियाँ नहीं)

कुछ चेतावनियों का उत्सर्जन करने के लिए डिफ़ॉल्ट नो-आर्ग gcc को बदलना मौजूदा लिपियों के लिए एक ब्रेकिंग परिवर्तन हो सकता है या सिस्टम बना सकता है। अच्छी तरह से डिजाइन किए गए या तो -Wallचेतावनियों से निपटते हैं, या व्यक्तिगत चेतावनियों को टॉगल करते हैं।

C ++ टूल चेन का उपयोग करना सीखना C ++ प्रोग्रामर बनना सीखना है, लेकिन C ++ टूल चेन आमतौर पर विशेषज्ञों द्वारा लिखी जाती है।


हाँ, मेरे Makefileपास मेरे पास इसके साथ चल रहा है -Wall -Wpedantic -Werror, लेकिन यह एक बार की परीक्षण स्क्रिप्ट थी जिसे मैं तर्कों की आपूर्ति करना भूल गया था।
निधि मोनिका का मुकदमा

2
एक उदाहरण के रूप में, टूटे हुए जीसीसी बूटस्ट्रैप -Wduplicated-condका हिस्सा बना -Wall। कुछ चेतावनियाँ जो अधिकांश कोड में उचित लगती हैं , सभी कोड में उचित नहीं हैं। इसलिए वे डिफ़ॉल्ट रूप से सक्षम नहीं हैं।
उह ओह किसी को जरूरत है एक प्यूपर

आपका पहला वाक्य स्वीकृत उत्तर "फ़्लॉइंग ऑफ .... अपरिभाषित व्यवहार ..." में उद्धरण के साथ विरोधाभास प्रतीत होता है। या ub को "कानूनी" माना जाता है? या क्या आपका मतलब है कि यह यूबी नहीं है जब तक कि (लौटाया नहीं) मूल्य वास्तव में उपयोग नहीं किया जाता है? मैं C ++ केस btw के बारे में चिंतित हूं
idclev 463035818

@ tobi303 एक फ़ंक्शन से int foo() { exit(-1); }वापस नहीं आता है intजो "int लौटने का दावा करता है"। यह C ++ में कानूनी है। अब, यह कुछ भी वापस नहीं करता है ; उस फंक्शन का अंत कभी नहीं हुआ। वास्तव में अंत तक पहुंचनाfoo अपरिभाषित व्यवहार होगा। प्रक्रिया के मामलों की समाप्ति को अनदेखा करना, int foo() { throw 3.14; }लौटने का दावा भी करता है intलेकिन कभी नहीं करता है।
यक्क - एडम नेवरामोंट

1
इसलिए मुझे लगता void* foo(void* arg) { pthread_exit(NULL); }है कि एक ही कारण के लिए ठीक है (जब इसका एकमात्र उपयोग है pthread_create(...,...,foo,...);)
idclev 463035818

1

मेरा मानना ​​है कि यह विरासत कोड की वजह से है (सी ने कभी आवश्यक विवरण नहीं दिया इसलिए सी ++)। उस "फ़ीचर" पर भरोसा करने वाला शायद बहुत बड़ा कोड है। लेकिन कम से कम -Werror=return-type कई कंपाइलरों (जीसीसी और क्लेंग सहित) पर झंडा है।


1

कुछ सीमित और दुर्लभ मामलों में, बिना मूल्य लौटाए गैर-शून्य फ़ंक्शन के अंत से बहना उपयोगी हो सकता है। निम्नलिखित MSVC- विशिष्ट कोड की तरह:

double pi()
{
    __asm fldpi
}

यह फ़ंक्शन x86 असेंबली का उपयोग करके pi देता है। GCC में असेंबली के विपरीत, मुझे returnपरिणाम में ओवरहेड को शामिल किए बिना ऐसा करने का कोई तरीका नहीं पता है ।

जहाँ तक मुझे पता है, मुख्यधारा C ++ संकलक को कम से कम अमान्य कोड के लिए चेतावनी का उत्सर्जन करना चाहिए। अगर मैं pi()खाली शरीर बनाता हूं , तो जीसीसी / क्लैंग एक चेतावनी की रिपोर्ट करेगा, और एमएसवीसी एक त्रुटि की रिपोर्ट करेगा।

लोगों ने अपवादों और exitकुछ उत्तरों में उल्लेख किया । वे वैध कारण नहीं हैं। या तो एक अपवाद को फेंकना, या कॉल करना, कार्य निष्पादन को अंत से प्रवाहित नहींexit करेगा । और संकलक इसे जानते हैं: एक फेंक बयान लिखना या खाली शरीर में कॉल करना संकलक से किसी भी चेतावनी या त्रुटियों को रोक देगा।exitpi()


MSVC विशेष रूप से एक गैर- voidफ़ंक्शन के अंत में गिरने का समर्थन करता है क्योंकि इनलाइन asm रिटर्न-वैल्यू रजिस्टर में एक मूल्य छोड़ देता है। ( st0इस मामले में x87 , पूर्णांक के लिए EAX। और शायद कॉलिंग कन्वेंशन में xmm0 जो st0 के बजाय xmm0 में फ्लोट / डबल लौटाता है)। इस व्यवहार को परिभाषित करना MSVC के लिए विशिष्ट है; -fasm-blocksएक ही वाक्य रचना का समर्थन करने के लिए भी यह सुरक्षित नहीं है। देखें __asm ​​{}; बाज का मूल्य लौटाओ?
पीटर कॉर्ड्स

0

किन परिस्थितियों में यह एक त्रुटि उत्पन्न नहीं करता है? यदि यह रिटर्न प्रकार घोषित करता है और कुछ वापस नहीं करता है, तो यह मेरे लिए एक त्रुटि की तरह लगता है।

एक अपवाद जो मैं सोच सकता हूं main(), वह फ़ंक्शन है, जिसमें returnसभी पर एक बयान की आवश्यकता नहीं है (कम से कम C ++ में; मेरे पास या तो सी मानकों का काम नहीं है)। यदि कोई रिटर्न नहीं है, तो यह कार्य करेगा जैसे return 0;कि अंतिम विवरण है।


1
main()returnसी। में जरूरत है
क्रिस लुत्ज़

@ जेफ्रोमी: ओपी एक गैर-शून्य फ़ंक्शन के बारे में एक return <value>;बयान के बिना पूछ रहा है
बिल

2
मुख्य स्वचालित रूप से C और C ++ में 0 देता है। C89 को एक स्पष्ट वापसी की आवश्यकता है।
जोहान्स स्काउब -

1
@ क्रिस: C99 return 0;में main()(और main()केवल) के अंत में एक निहित है । लेकिन यह return 0;वैसे भी जोड़ने के लिए अच्छी शैली है ।
दोपहर

0

लगता है जैसे आपको अपने संकलक चेतावनी को चालू करने की आवश्यकता है:

$ gcc -Wall -Wextra -Werror -x c -
int main(void) { return; }
cc1: warnings being treated as errors
<stdin>: In function main’:
<stdin>:1: warning: return with no value, in function returning non-void
<stdin>:1: warning: control reaches end of non-void function
$

5
"टर्न ऑन -वायर" कहना एक गैर-उत्तर है। स्पष्ट रूप से चेतावनियों और त्रुटियों के रूप में वर्गीकृत मुद्दों के बीच गंभीरता में अंतर है, और जीसीसी इसे कम गंभीर वर्ग के रूप में मानता है।
कैस्केबेल

2
@ जेफ्रोमी: शुद्ध भाषा के दृष्टिकोण से, चेतावनी और त्रुटियों में कोई अंतर नहीं है। कंपाइलर को केवल "अव्यवस्थित संदेश" जारी करने की आवश्यकता होती है। संकलन को रोकने या कुछ "एरोर" और कुछ और "चेतावनी" कहने की आवश्यकता नहीं है। एक डायग्नोस्टिक संदेश जारी किया जाता है (या किसी भी प्रकार का), यह पूरी तरह से आप पर निर्भर है कि आप क्या निर्णय लेते हैं।
चींटी

1
फिर, प्रश्न में समस्या यूबी का कारण बनती है। यूबी को पकड़ने के लिए कंपाइलरों की आवश्यकता नहीं होती है।
21:39

1
6.9.1 / 12 में n1256 में यह कहा गया है कि "यदि} जो कि किसी फ़ंक्शन को समाप्त करता है, तो पहुँच जाता है, और कॉल करने वाले द्वारा फ़ंक्शन कॉल के मूल्य का उपयोग किया जाता है, व्यवहार अपरिभाषित होता है।"
जोहान्स स्काउब -

2
@ क्रिस लुत्ज़: मैं इसे नहीं देखता। यह एक गैर-शून्य फ़ंक्शन में एक स्पष्ट खाली का उपयोग करने के लिए एक बाधा उल्लंघन है return;, और यह return <value>;एक शून्य फ़ंक्शन में उपयोग करने के लिए एक बाधा उल्लंघन है । लेकिन यह मेरा मानना ​​है कि विषय नहीं। ओपी, जैसा कि मैंने समझा, यह गैर-शून्य फ़ंक्शन से बाहर निकलने के बारे में है बिना return(बस फ़ंक्शन के अंत से बाहर प्रवाह को नियंत्रित करने की अनुमति देता है)। यह एक बाधा उल्लंघन नहीं है, AFAIK। मानक बस यह कहता है कि यह हमेशा C ++ में UB है और कभी-कभी UB में C.
AnT

-2

यह c99 में एक बाधा उल्लंघन है, लेकिन c89 में नहीं। कंट्रास्ट:

C89:

3.6.6.4 returnबयान

प्रतिबन्ध

एक returnअभिव्यक्ति के साथ एक बयान एक फ़ंक्शन में प्रकट नहीं होगा जिसका रिटर्न प्रकार है void

c99:

6.8.6.4 returnबयान

प्रतिबन्ध

एक returnअभिव्यक्ति के साथ एक बयान एक फ़ंक्शन में प्रकट नहीं होगा जिसका रिटर्न प्रकार है void। एक returnअभिव्यक्ति के बिना एक बयान केवल एक फ़ंक्शन में दिखाई देगा जिसका रिटर्न प्रकार है void

यहां तक ​​कि --std=c99मोड में, जीसीसी केवल एक चेतावनी फेंक देगा (हालांकि अतिरिक्त -Wझंडे को सक्षम करने की आवश्यकता के बिना , जैसा कि डिफ़ॉल्ट रूप से या c89 / 90 में आवश्यक है)।

C89 में इसे जोड़ने के लिए संपादित करें, " }उस तक पहुंचने वाला एक फ़ंक्शन returnएक अभिव्यक्ति के बिना एक कथन को निष्पादित करने के बराबर है " (3.6.6.4)। हालाँकि, c99 में व्यवहार अपरिभाषित है (6.9.1)।


4
ध्यान दें कि यह केवल स्पष्ट returnविवरण शामिल करता है । यह किसी मान को वापस किए बिना किसी फ़ंक्शन के अंत में गिरने को कवर नहीं करता है।
जॉन कुगेलमैन

3
ध्यान दें कि C99 को "उस} तक पहुंचने में चूक होती है जो एक फ़ंक्शन को समाप्त करता है, एक अभिव्यक्ति के बिना रिटर्न स्टेटमेंट निष्पादित करने के बराबर है" इसलिए इसे एक बाधा उल्लंघन नहीं बनाया गया है, और इस प्रकार किसी भी निदान की आवश्यकता नहीं है।
जोहान्स स्काउब -
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.