2011-12-30 10 views
116

मैं सिर्फमुख्य यहाँ क्यों वापस नहीं आता है?

आईएसओ/आईईसी 9899 पढ़ रहा था: 201x समिति ड्राफ्ट - 12 अप्रैल, 2011

जिसमें मैं 5.1.2.2.3 कार्यक्रम समाप्ति के नीचे पाया

..reaching the } that terminates the main function returns a value of 0. 

इसका मतलब है यदि आप main() में कोई रिटर्न स्टेटमेंट निर्दिष्ट नहीं करते हैं, और यदि प्रोग्राम सफलतापूर्वक चलता है, तो मुख्य के समापन ब्रेस} पर 0

लेकिन अनुयायी में कारण कोड मैं किसी भी वापसी कथन का उल्लेख नहीं करते, फिर भी यह वापस नहीं करता है 0

#include<stdio.h> 
int sum(int a,int b) 
{ 
return (a + b); 
} 

int main() 
{ 
    int a=10; 
    int b=5; 
    int ans;  
    ans=sum(a,b); 
    printf("sum is %d",ans); 
} 

संकलन

gcc test.c 
./a.out 
sum is 15 
echo $? 
9   // here it should be 0 but it shows 9 why? 
+0

क्या आपने सी 99 (या अधिक) कंपाइलर के साथ संकलित किया था? चश्मा पढ़ने के लिए धैर्य रखने के लिए – pmg

+69

+1 ..... – Asher

+0

मैंने जीसीसी के साथ कोई अतिरिक्त विकल्प/ध्वज नहीं संकलित किया है? –

उत्तर

140

वह नियम सी मानक के 1999 संस्करण में जोड़ा गया है। सी 0 9 में, लौटाई गई स्थिति अपरिभाषित है।

आप जीसीसी में -std=c99 पास करके इसे सक्षम कर सकते हैं।

एक साइड नोट के रूप में, दिलचस्प रूप से 9 वापस कर दिया गया है क्योंकि यह printf की वापसी है जिसने अभी 9 वर्ण लिखे हैं।

+8

धन्यवाद। gcc -std = c99 test.c 0 –

+40

देता है या आप क्लोजिंग '}' से पहले 'वापसी 0;' जोड़ सकते हैं। यह हानिरहित है और आपके प्रोग्राम को पुराने कंपाइलर्स को पोर्टेबल बनाता है। –

+0

करता है} मुख्य वापसी की वापसी 0 सी 99 में या सी के पुराने संस्करण के हिस्से में जोड़ा जाता है? –

15

यह printf का रिटर्न मूल्य देता है जो वास्तव में मुद्रित वर्णों की संख्या है।

+0

प्रश्न कंसोल में मुद्रित होने के बारे में बात नहीं करता है, प्रोग्राम को निष्पादित करते समय, यह प्रोग्राम के वापसी मूल्य के बारे में बात करता है: (आप इसे लिनक्स में स्कील कमांड के साथ प्राप्त कर सकते हैं: echo $? और विंडोज़ में: echo% errorlevel%) –

+1

@eharvest हालांकि मुझे नहीं पता कि विंडोज़ में '% errorlevel%' की जांच कैसे करें, बाहर निकलने के कोड और लिनक्स में 'मुख्य' के वापसी मूल्य के बीच कोई अंतर? –

+1

@eharvest: उत्तर कंसोल में मुद्रित किए जाने के बारे में भी बात नहीं करता है। यह किसी भी तरह 'main' से' printf' जो इस मामले में 9 जो तब हो जाता है है की _return value_ बारे में बात करती बाहर निकलने के कोड के रूप में "पदोन्नत" जब कुछ जीसीसी संस्करणों का उपयोग। –

6

फ़ंक्शन से वापसी मूल्य आमतौर पर सीपीयू के ईएक्स रजिस्टर में संग्रहीत होता है, इसलिए कथन "वापसी 4;" आमतौर पर

mov eax, 4; 
ret; 

के संकलन और वापसी एक्स (अपने संकलक के आधार पर) हैं कुछ की तरह होगा:

mov eax, [ebp + 4]; 
ret; 

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

यह एक सरल स्पष्टीकरण है, विभिन्न कॉलिंग सम्मेलन और लक्ष्य प्लेटफ़ॉर्म महत्वपूर्ण भूमिका निभाएंगे लेकिन यह आपके उदाहरण में 'दृश्यों के पीछे' क्या हो रहा है, यह समझाने के लिए पर्याप्त जानकारी होनी चाहिए।

यदि आपको असेंबलर की बुनियादी समझ मिल गई है तो यह विभिन्न कंपेलरों के डिस्सेप्लर की तुलना करने योग्य है। आप पाएंगे कि कुछ कंपाइलर ईएक्स रजिस्टर को एक सुरक्षा के रूप में साफ़ कर रहे हैं।

+11

कंपाइलर _might_ ऐसा करता है। यह अपरिभाषित है। यह आपको प्रिंटर कारतूस के साथ सिर में शूट करने का विकल्प चुन सकता है। मानक पारित होने के इस परिभाषित उद्धरण: –

+0

@LightnessRacesinOrbit अपरिभाषित अप्रत्याशित, यानी से के रूप में ही नहीं है, यह तार्किक का पालन नहीं करता – Owen

+0

@Owen "संकलक एक्स कर सकता" "यदि संकलक करता है एक्स, यह मानक के अनुरूप हो जाएगा"। –

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