"Int main () {([() {}} ());}" मान्य C ++ कैसे है?


271

मैं हाल ही में कोड के निम्नलिखित गूढ़ टुकड़े में आया था।

int main(){(([](){})());}

इसे और अधिक पठनीय बनाने के लिए निम्नानुसार सुधार करें:

int main(){
    (([](){})());   //  Um... what?!?!
}

लेकिन मुझे अपना सिर नहीं मिल रहा है कि कैसे (([](){})())वैध कोड है।

  • यह फ़ंक्शन पॉइंटर सिंटैक्स की तरह नहीं दिखता है।
  • यह कुछ ऑपरेटर ओवरलोडिंग ट्रिक नहीं हो सकता है। कोड के रूप में संकलित है।

Google ने इस सभी-प्रतीक खोज में बहुत मदद नहीं की। लेकिन यह दृश्य स्टूडियो 2010 में संकलित करता है और कुछ भी नहीं आउटपुट करता है। कोई त्रुटि नहीं थी, और कोई चेतावनी नहीं थी। तो यह मान्य कोड जैसा दिखता है।

मैंने ऐसा कोई भी मान्य कोड कभी नहीं देखा है जो जावास्क्रिप्ट और सी फंक्शन पॉइंटर्स के बाहर इतना विचित्र हो ।

क्या कोई समझा सकता है कि यह वैध C ++ कैसे है?


94
अरे! वह मेरा है। "Don't sweat it. We have int main(){(([](){})());} which is valid C++" (चैट में नवंबर 9 वीं)
sehe

31
यह एक c ++ 11

7
@Mysticial - यह कोड आपको रहस्यमय बनाता है क्योंकि यह बेकार है। यदि यह लैम्ब्डा कुछ करता है, तो आप इसे फ़ंक्शन पॉइंटर्स के समान सिंटैक्स वाले पहचानेंगे (जिसके साथ यह निकटता से संबंधित है)।
SChepurin

14
@ सिस्टिक - "6 साल का C ++" - लैम्ब्डा को सिर्फ C ++ 11 में जोड़ा गया था, इसलिए किसी को भी उनके साथ एक साल या उससे पहले का अनुभव नहीं है।
पीट बेकर

50
यहाँ URL काफी मनोरंजक है: "
हाउ

जवाबों:


283

कोड अनिवार्य रूप से एक खाली मेमने को बुलाता है।

आइए शुरुआत से शुरू करें: [](){}एक खाली लंबोदर अभिव्यक्ति है

फिर, सी और C ++, आप कोष्ठक में भाव लपेट कर सकते हैं और वे ठीक उसी तरह से व्यवहार के रूप में यदि उनके बिना लिखा है, तो चलो क्या लैम्ब्डा के आसपास कोष्ठक की पहली जोड़ी करता है। अब हम पर हैं ([](){})

फिर, ()पहली रैपिंग परेंस के बाद (खाली) लंबा कॉल करता है। अब हम पर हैं([](){})()

पूरी अभिव्यक्ति फिर से परनों में लिपटी है और हमें मिलती है (([](){})())

आखिर ;में बयान खत्म करता है। हम पहुंचते हैं (([](){})());


† कम से कम C ++ में कुछ कोने के मामले हैं, जैसे कि T a_var; इसके बीच अंतर है decltype(a_var)औरdecltype((a_var))



33
@ R.MartinhoFernandes: यह अभी भी किसी में अटका हुआ था, इसलिए मुझे इसे पुनः प्राप्त करना पड़ा।
Xeo

1
मैं उस मामले का सही ढंग से उल्लेख करने जा रहा था जहां एक अभिव्यक्ति के चारों ओर जोड़ना () शब्दार्थ को बदल देता है। लेकिन फिर मुझे याद आया कि इसका सवाल से कोई संबंध नहीं है, वास्तव में। अच्छा उत्तर
10

2
कोष्ठक भी सबसे डरावने पार्स विघटन के मामले में एक कार्यक्रम के अर्थ को बदल रहे हैं: B foo(A())फू एक फ़ंक्शन है (केवल एक पैरामीटर के रूप में कार्य करने के लिए एक सूचक ले रहा है और एक बी वापस आ रहा है) जबकि B foo((A()))फू में एक बी ऑब्जेक्ट का निर्माण किया जाता है जो एक कंस्ट्रक्टर ले जा रहा है एक वस्तु (जो उदाहरण इस मामले में एक अस्थायी अस्थायी है)।
विज्ञापन एन

1
@ विज्ञापन: यह एक अभिव्यक्ति नहीं है, लेकिन एक घोषणा है।
Xeo
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.