2011-09-28 16 views
9

इसे जीसीसी 4.6 में आजमाया और यह संकलित और लिंक करता है, लेकिन मैकोज़ पर रनटाइम पर "बस त्रुटि" संदेश देता है। वीएस -2010 इसे संकलित भी नहीं करता है।क्या यह सही सी ++ 0x कोड है?

लेकिन सवाल यह है कि, क्या यह वास्तव में मानक सी ++ 0x में काम करना चाहिए?

#include <cstdio> 
int (*main)()=[]()->int{printf("HEY!\n");return 0;}; 

हां, यह करने की कोशिश कर रहा है कि "मुख्य" को लैम्ब्डा फ़ंक्शन के रूप में परिभाषित करना है।

+13

मुझे सी ++ 11 की नवीनतम, सबसे बढ़िया, उन्नत विशेषताओं का उपयोग करने का तरीका पसंद है, लेकिन अभी भी 'cstdio' और' printf' :-) – paxdiablo

+4

@paxdiablo: printf चट्टानों का उपयोग करने पर जोर देना !!! सी ++ I/O धाराओं में विफल रहा :) –

+1

स्ट्राउस्ट्रुप के अनुसार ... यदि सी आपको पैर में शूट करने देता है, तो सी ++ आपके सारे पैर को उड़ सकता है! यही वह है जिसे मैं बुलाता हूं ... मासोचिज्म! :-)) –

उत्तर

14

यह वैध सी ++ प्रोग्राम नहीं है, क्योंकि प्रतीक main को फ़ंक्शन होने के लिए परिभाषित नहीं किया गया है, बल्कि कार्य करने के लिए एक सूचक है। यही कारण है कि आप सेगमेंटेशन गलती प्राप्त करते हैं - रनटाइम एक पॉइंटर निष्पादित करने का प्रयास कर रहा है।

+0

+1: (मूल प्रश्न पर मेरी नीची टिप्पणी हटा दी गई है। उस उत्तर का प्रकार बेहतर बताता है कि यहां क्या हो रहा है।) –

+0

तो मुझे लगता है कि यह वास्तव में जीसीसी में एक बग है कि यह इस कोड को सही मानता है? – hasvn

+0

@ हसन, मुझे यकीन नहीं है, लेकिन मुझे लगता है कि यह उन उदाहरणों में से एक है जिसमें मानक द्वारा कोई निदान की आवश्यकता नहीं है। तो जीसीसी स्पष्ट में हो सकता है। – avakar

3

नहीं, यह सही नहीं है।

मुख्य एक विशेष कार्य है और इसके लिए सख्त आवश्यकताएं हैं (नियमित कार्य से भी अधिक सख्त), लेकिन आप फ़ंक्शन के बीच कुछ भ्रम भी कर रहे हैं और फ़ंक्शन के लिए पॉइंटर क्या है।

तार्किक समस्या यह है कि फ़ंक्शन और एक चर के बीच एक अंतर होता है जिसमें एक फ़ंक्शन में एक पॉइंटर होता है (जो आप मुख्य होना चाहते हैं)। किसी फ़ंक्शन में स्मृति में एक निश्चित पता होता है, इसलिए उस फ़ंक्शन को कॉल करने के लिए जिसे पता कहा जाता है। एक फंक्शन अंक मेमोरी में किसी पते पर एक पॉइंटर, इसलिए उस फ़ंक्शन को कॉल करने के लिए जिसे आपको पहले पॉइंटर इंगित करने के लिए आवश्यक है और फिर उस पते को कॉल करें।

फ़ंक्शन के लिए एक पॉइंटर में फ़ंक्शन से एक अलग स्तर का संकेत होता है। यदि x बजाय एक समारोह (एक सूचक एक मूल्य होना चाहिए के मामले में है अगर x एक समारोह के लिए एक सूचक आप x(42) लिख सकते हैं, लेकिन अभी भी उत्पन्न मशीन कोड अलग है

वाक्य रचना एक ही ... यानी है देखा जाना चाहिए और कॉल पता रन टाइम पर निर्धारित किया जाता है, एक फंक्शन के साथ पता तय किया जाता है - स्थानांतरण के लिए - और लिंक समय पर निर्धारित किया जाता है)।

0

कंपाइलर्स और मानक लाइब्रेरी कार्यान्वयन के बीच पोर्टेबिलिटी के लिए, printf() std :: printf() होना चाहिए जब #शामिल हो। और अमान्य मुख्य() के बारे में अन्य सामान।

+0

नहीं, यह मानक में निर्दिष्ट नहीं है कि 'cXXX' में वैश्विक नामस्थान में इंजेक्शन शामिल है या नहीं। 'Std :: 'का उपयोग करने के लिए यह _wise_ है लेकिन" जरूरी "शायद एक ओवरकिल है। – paxdiablo

+0

ठीक है, यह वैसे भी एक आधा मज़ाक था। मैं जवाब को संपादित कर दूंगा कि यह पोर्टेबिलिटी के लिए आवश्यक है। (हम में से जो जीवित रहने के लिए पोर्टेबल कोड लिखते हैं, बस इस तरह से सोचना शुरू करें ...) –

0

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

कंपाइलर के आधार पर, main फ़ंक्शन में सी ++ या सी लिंकेज हो सकता है (यह कार्यान्वयन परिभाषित किया गया है)। लैम्ब्डा अभिव्यक्ति फ़ंक्शन कॉल ऑपरेटर के साथ C++ प्रकार लौटाती है, इस प्रकार सी ++ लिंकेज।

+0

वास्तव में एक गैर-कैप्चरिंग लैम्ब्डा से एक फ़ंक्शन पॉइंटर में एक निहित रूपांतरण है। – avakar

+0

उद्धरण: (5.1.2/6)। –

+0

आप दोनों सही हैं। हालांकि, यह निहित रूप से सूचक कार्य में सूचक को परिवर्तित करता है, न कि एक मुक्त कार्य। अस्पष्ट रूप से याद रखना कि मुझे भ्रमित कर सकता है। – mloskot

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