2011-12-06 16 views
15

एक अल्पज्ञात, लेकिन लगभग कभी नहीं इस्तेमाल किया सी ++ सुविधा एक घोषणा दिया जाता है जो this की अनुमति देने के समान लगता है।समारोह कोशिश पकड़ वाक्य रचना और मुख्य

क्या int main() के लिए यह कानूनी है? उदाहरण के लिए:

int main() try { 
    throw 42; 
} 
catch(...) { 
} 

The rules for main, n3290 § 3.6.1 ज्यादातर के बारे में क्या तर्क यह लेना चाहिए और क्या यह रिटर्न बात - वे स्पष्ट रूप से इसे ना करे के रूप में वे विभिन्न अन्य अजीब चीजों के साथ क्या नहीं है (उदाहरण के लिए लिंकेज) आप कोशिश करने के लिए लुभाने हो सकता है।

क्या यह कानूनी और अच्छी तरह से परिभाषित है?

+2

दिलचस्प अकादमिक प्रश्न, हालांकि मुझे यकीन नहीं है कि इसका व्यावहारिक उपयोग है। http://stackoverflow.com/a/620817/10077 –

+0

कानूनी? तकनीकी रूप से अधिकांश कंपाइलर्स इसका समर्थन करेंगे। अच्छी तरह से परिभाषित? वास्तव में नहीं, क्योंकि मैं निश्चित रूप से ऐसा करने के किसी भी कारण के बारे में नहीं सोच सकता। – AJG85

+0

@ AJG85 - मेरा मतलब है "न तो अपरिभाषित व्यवहार, न ही कार्यान्वयन परिभाषित व्यवहार का आह्वान", "अच्छी तरह से परीक्षण में सामान्य परीक्षण" तरीके से नहीं, – Flexo

उत्तर

7

[basic.start.main] के भीतर इसके उपयोग न करे नहीं है, और, समर्थन करने के लिए सभी कार्यान्वयन के लिए मजबूर करते हुए कम से कम int main() {/*...*/ } और int main(int argc, char* argv[]) {/*...*/}, उन दो घोषणाओं (3.6.1, पैरा 2) में कार्यान्वयन को सीमित नहीं करता है।

उस अलगाव में, यह कम से कम दिखाई देगा कि यह कानूनी है, बेशक यह केवल कार्य-घोषणाओं से संबंधित है, कार्य-परिभाषाओं से संबंधित नहीं है।

पर पढ़ना, [except.handle], पैरा 13 राज्यों निम्नलिखित:

अपवाद स्थिर भंडारण अवधि के साथ या नाम स्थान-गुंजाइश वस्तुओं के निर्माताओं में वस्तुओं की विनाशकर्ता में फेंक दिया एक से पकड़ा नहीं कर रहे हैं मुख्य() पर फ़ंक्शन-ट्राई-ब्लॉक। (15.3 पैरा। 13)

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

ब्लॉग पोस्ट मैं इस जवाब के पहले संस्करण में आपूर्ति की वास्तव में करता है ऊपर ब्लॉककोट द्वारा दिए गए नियमों को दर्शाता हुआ की एक अच्छा काम है, इसलिए मैं retain the link to it हूँ, भले ही यह सीधे ओपी के दशक में इस मुद्दे पर चर्चा नहीं करता है सवाल।

ओपी पर एक टिप्पणी के संबंध में, आप फ़ंक्शन-ट्राई-ब्लॉक, और [छोड़कर) के भीतर वापसी विवरण जारी कर सकते हैं।हैंडल] यह कहने के लिए है:

फ़ंक्शन-ट्राई-ब्लॉक के अंत में बहने से कोई मूल्य नहीं है; इसके परिणामस्वरूप मूल्य-वापसी फ़ंक्शन (6.6.3) में अपरिभाषित व्यवहार होता है। (15.3 पैरा। 15)

आप main के अंत में एक कैच-ब्लॉक में हैं, तो आप समारोह के शरीर पर प्रवाह के लिए नहीं जा रहे हैं (इस मामले में कोशिश-ब्लॉक किया जाएगा जो) , इसलिए नियम जो मुख्य रूप से फ़्लोवर पर return 0; पर कॉल करता है, लागू नहीं होता है। अपरिभाषित होने से रोकने के लिए आपको कुछ int (काफी संभवतः एक त्रुटि कोड) वापस करने की आवश्यकता है।

+1

अधिक जानकारी (परिभाषा पर) नहीं, 'स्थैतिक' कन्स्ट्रेटेशन अपेक्षाकृत सरल हैं: 'वैश्विक' वस्तुओं को 'मुख्य' कहा जाता है और इसे वापस करने के बाद नष्ट कर दिया जाता है ... इसलिए स्पष्ट रूप से 'कोशिश/पकड़' के भीतर नहीं ब्लॉक। कन्स्ट्रक्टर सिंटैक्स पर टिप्पणियों के लिए, हाँ यह अजीब है लेकिन वास्तव में सवाल का जवाब नहीं देता है ... –

+0

मैं उस मूल्यांकन से सहमत हूं, और इसे नोट किया है; धन्यवाद। मुझे 'मुख्य()' फ़ंक्शन-ट्राई-ब्लॉक होने का स्पष्ट संदर्भ मिला, इसलिए मुझे लगता है कि लेख वैसे भी बेकार है। मैं इसे स्पष्ट करने के लिए एक संपादन करूँगा। – matthias

+0

15.3 से यह उद्धरण बहुत दिलचस्प है।(यह संभवतः मेरा अगला प्रश्न होने वाला था यदि यह कानूनी था) डीआर के साथ संयुक्त जो जोहान्स जो उससे जुड़ा हुआ है, उसे उत्तर देने के लिए उत्तर देने लगता है। – Flexo

0

मैंने कोशिश की है, यह संकलित करता है, और यह अपेक्षा के अनुसार चलता है। एक असाधारण फॉर्मूलेशन, लेकिन मुझे नहीं लगता कि यह किसी भी नियम को तोड़ देता है। स्पष्टता (खुद के लिए और भविष्य के कोड mantainers) के लिए, आप भी इसे अलग तरीके से व्यक्त कर सकता है के रूप में: मानक

int main() 
{ 
    try { 
     throw 42; 
    } 
    catch(int /*...*/) { 
    } 
} 
+4

यह मेरे कंपाइलर पर भी काम करता है। "यह संकलित करता है और चलता है" के साथ समस्या यह है कि मैं अपने कंपाइलर संकलन को जानता हूं और बहुत सी चीजें चलाता हूं जो अच्छी तरह परिभाषित नहीं हैं। – Flexo

+1

उचित बिंदु, @awoodland। इसलिए, संदेह में, मैं ऊपर उल्लिखित फॉर्मूलेशन का उपयोग करने का सुझाव दूंगा, जो आपको वही करना है जो आपको चाहिए। हालांकि आपका मूल फॉर्मूलेशन मानक से किसी भी नियम को तोड़ने लगता नहीं है। – alexandreC