2012-07-15 50 views
9

ठीक है तो मैं Ideone पर गड़बड़ कर रहा था और गलती से कोड का यह टुकड़ा जमा कर दिया, हालांकि मेरे आश्चर्य के लिए यह वास्तव में संकलित और 0, here के मूल्य को आउटपुट चला गया।यह विचार पर संकलित क्यों करता है?

#include <iostream> 

using namespace std; 

const int five() 
{ 
     const int i = 5; 
} 

int main() { 
     cout << five() << endl; 
     return 0; 
} 

मैं तो दृश्य स्टूडियो में इस की कोशिश की, और Codepad पर फिर भी दोनों को संकलित करने क्योंकि five() एक मूल्य वापस नहीं करता है, के रूप में एक उम्मीद होती है विफल रहा है। मेरा सवाल, ज़ाहिर है, यह Ideone पर ठीक क्यों संकलित करता है, भले ही कोड मेरी समझ में गलत है और संकलित नहीं होना चाहिए।

उत्तर

14

सादा और बस (सी ++ 11 6.6.3 "वापसी कथन" से):

एक समारोह के अंत की ओर बहने वाली कोई मूल्य नहीं के साथ एक लाभ के समतुल्य है, यह मूल्य-वापसी कार्य में अपरिभाषित व्यवहार में परिणाम देता है।

तो संकलक को जो कुछ भी चाहिए वह करने की अनुमति है। जाहिर है, एक निदान एक संकलक से कुछ पसंद है, लेकिन ऐसे समय होते हैं जब निदान करना मुश्किल हो सकता है (जैसे कि वापसी सशर्त तर्क के अंदर होती है, और समारोह का 'अंत' कभी नहीं पहुंचाया जाएगा)।

ध्यान दें कि मैं जीसीसी 4.6.1 (Wall विकल्प का उपयोग) के साथ निम्न चेतावनी मिलती है:

test.cpp:8:1: warning: no return statement in function returning non-void [-Wreturn-type] 

मुझे यकीन है कि क्या विकल्प ideone जीसीसी के पास रहता है (मुझे लगता है कि -Wall भी ऐसा ही होगा नहीं कर रहा हूँ 4.3.4 संस्करण के साथ जो विचारधारा उपयोग करता है)।

कुछ संबंधित जानकारी:

सी में यह एक समारोह है कि एक मूल्य के वापस जाने के लिए घोषित किया जाता है के लिए ठीक है के लिए वास्तव में नहीं तो कुछ निश्चित परिस्थितियों में करते हैं; सी में केवल अपरिभाषित व्यवहार में परिणाम होता है यदि फ़ंक्शन का रिटर्न वैल्यू वास्तव में प्रयुक्त होता है। प्री-स्टैंडर्ड सी हमेशा void प्रकार का समर्थन नहीं करता था, इसलिए कुछ भी वापस नहीं किए गए फ़ंक्शंस को स्पष्ट रूप से या निहित रूप से int वापस करने के लिए घोषित किया गया था। सी 99 6.9.1/12 "फंक्शन परिभाषाएं" से: यदि } जो फ़ंक्शन को समाप्त करता है, और कॉलर द्वारा फ़ंक्शन कॉल का मान उपयोग किया जाता है, तो व्यवहार अपरिभाषित होता है।

इसके अलावा, जैसा कि कुछ टिप्पणियों में उल्लेख किया गया है, main() के अंत में बहने वाला विशेष रूप से सी ++ और सी 99 और बाद में इलाज किया जाता है।

+0

क्या आप उद्धरण के स्रोत का संदर्भ ले सकते हैं? –

+0

@ डेसमंडम: मानक। – Xeo

+1

एकमात्र समय यह अच्छी तरह से परिभाषित किया गया है 'मुख्य' –

3

गैर-शून्य कार्य से मूल्य वापस नहीं करना एक गलती है, लेकिन सभी कंपाइलर इसे एक त्रुटि के रूप में नहीं मानते हैं - उदाहरण के लिए, जीसीसी केवल इससे चेतावनी देता है जब यह सामना करता है। अन्य कंपाइलर पागल हो सकते हैं (और वे सही हैं) और आपको ऐसे कोड को संकलित करने की अनुमति न दें। बेशक कंपाइलर व्यवहार अलग-अलग स्विच और विकल्पों का उपयोग करके संशोधित किया जा सकता है।

0 का वापसी मूल्य केवल एक यादृच्छिक मूल्य है - यह समान रूप से 255, -1 या कोई अन्य कचरा हो सकता है, क्योंकि यह अनिर्धारित व्यवहार है (मुख्य को छोड़कर, जिसके लिए सी 99 निर्दिष्ट करता है कि एक निहित 0 वापसी मूल्य माना जाना चाहिए)।

3

ऐसा प्रतीत होता है कि विचारधारा चेतावनी प्रदर्शित नहीं करता है, अगर कोई त्रुटि हुई तो यह केवल कंपाइलर आउटपुट प्रदर्शित करता है। जीसीसी के संस्करण पर जो विचारधारा का उपयोग कर रहा है (जीसीसी 4.3) यह कोई त्रुटि नहीं है, यह सिर्फ एक चेतावनी है।

2

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

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