2010-08-09 11 views
7

मैंने हाल ही में comp.lang.C++ पर कोड का एक टुकड़ा देखा है जो एक फ़ंक्शन से स्थिर पूर्णांक का संदर्भ लौटाता है। कोड इससमयपूर्व अनुकूलन या मैं पागल हूँ?

int& f() 
{ 
    static int x; 
    x++; 
    return x; 
} 

int main() 
{ 
    f()+=1; //A 
    f()=f()+1; //B 
    std::cout<<f(); 

} 

की तरह कुछ था जब मैं अपने शांत विजुअल स्टूडियो डीबगर का उपयोग कर आवेदन डिबग मैं बयान एक करने के लिए सिर्फ एक कॉल को देखा और लगता है कि क्या मैं हैरान था। मैंने हमेशा सोचा i+=1i=i+1 के बराबर था इसलिए f()+=1f()=f()+1 के बराबर होगा और मुझे f() पर दो कॉल दिखाई देगी, लेकिन मैंने केवल एक देखा। यह क्या बकवास है? क्या मैं पागल हूं या मेरा डीबगर पागल हो गया है या क्या यह समयपूर्व अनुकूलन का परिणाम है?

+4

'स्थिर int x' अनियमित है। –

+1

हालांकि, सवाल से संबंधित नहीं है। – BjoernD

+1

@ रैम्बो: मुझे लगता है कि आप इस धागे के बारे में बात कर रहे हैं: http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/566222d9b756ecc5/3279970278f46946 –

उत्तर

27

इस मानक क्या कहते है += के बारे में और दोस्तों:

5.17-7: एक अभिव्यक्ति का व्यवहार प्रपत्र E1 सेशन के = E2 कि ई 1 को छोड़कर E1 = E1 सेशन E2 के बराबर है केवल एक बार का मूल्यांकन किया है। [...]

तो संकलक सही है कि चल रहा है।

+4

अच्छा लगता है। _______________ :-) –

10

i+=1कार्यात्मक रूप सेi=i+1 जैसा ही है। यह वास्तव में अलग-अलग कार्यान्वित किया जाता है (मूल रूप से, यह सीपीयू स्तर अनुकूलन का लाभ लेने के लिए डिज़ाइन किया गया है)।

लेकिन संक्षेप में बाएं तरफ का मूल्यांकन केवल एक बार किया जाता है। यह एक गैर-कॉन्स एल-वैल्यू उत्पन्न करता है, जिसे इसे मूल्य पढ़ने, इसे जोड़ने और इसे वापस लिखने की आवश्यकता होती है।

यह अधिक स्पष्ट है जब आप कस्टम प्रकार के लिए अधिभारित ऑपरेटर बनाते हैं। operator+=this उदाहरण को संशोधित करता है। operator+ एक नया उदाहरण देता है। आमतौर पर ओओपी + = पहले लिखने के लिए (सी ++ में) अनुशंसा की जाती है, और उसके बाद ओप + लिखते हैं।

(ध्यान दें यह है केवल सेल्सियस तक ++ लागू होता है, सी # में, op+= बिल्कुल के रूप में आप मान लिया है:। op+ के लिए बस एक छोटी हाथ, और आप अपने खुद के सेशन का निर्माण नहीं कर सकते हैं + = यह स्वचालित रूप से Op + से बाहर आप के लिए बनाई गई है)

9

आपकी सोच तार्किक है लेकिन सही नहीं है।

i += 1; 
// This is logically equivalent to: 
i = i + 1; 

लेकिन तर्कसंगत समकक्ष और समान समान नहीं हैं।
कोड इस तरह लग रही के रूप में देखा जाना चाहिए:

int& x = f(); 
x += x; 
// Now you can use logical equivalence. 
int& x= f(); 
x = x + 1; 

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

3

f() स्थिर पूर्णांक का संदर्भ देता है। तब += 1 इस स्मृति स्थान – करने के लिए एक कहते बयान ए में दो बार इसे कहते हैं कोई आवश्यकता नहीं है

0

प्रत्येक भाषा में मैंने देखा है कि एक + = ऑपरेटर का समर्थन करता है, तो कंपाइलर एक प्रकार का पता उत्पन्न करने के लिए बाएं हाथ के ऑपरेंड का मूल्यांकन करता है जिसका उपयोग पुराने मूल्य को पढ़ने और लिखने के लिए किया जाता है नया। + = ऑपरेटर सिर्फ वाक्य रचनात्मक चीनी नहीं है; जैसा कि आप ध्यान देते हैं, यह अभिव्यक्ति अर्थशास्त्र प्राप्त कर सकता है जो अन्य माध्यमों के माध्यम से प्राप्त करने के लिए अजीब होगा।

संयोग से, vb.net और पास्कल में "साथ" बयान दोनों में एक समान सुविधा है। एक बयान जैसे:

 
' Assime Foo is an array of some type of structure, Bar is a function, and Boz is a variable. 
    With Foo(Bar(Boz)) 
    .Fnord = 9 
    .Quack = 10 
    End With 
फू (बार (बोज़)) के पते की गणना करेगा, और फिर उस संरचना के दो फ़ील्ड को नौ और दस मानों पर सेट करेगा। यह सी से

 
    { 
    FOOTYPE *tmp = Foo(Bar(Boz)); 
    tmp->Fnord = 9; 
    tmp->Quack = 10; 
    } 

लेकिन vb.net और पास्कल अस्थायी सूचक का खुलासा नहीं करेगा। जबकि कोई भी "साथ" का उपयोग किए बिना "साथ" का उपयोग किए बिना VB.net में उसी प्रभाव को प्राप्त कर सकता है, "साथ" का उपयोग करके अस्थायी चर से बचने की अनुमति मिलती है।

+0

जाहिर है उदा। सी # एलएचएस का दो बार मूल्यांकन करता है क्योंकि जेम्स अपने जवाब में बताते हैं। –

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