2013-02-26 16 views
7

अगर मैं एक कार्यक्रम है:अप्रयुक्त फ़ंक्शन रिटर्न मानों का क्या होता है?

#include <iostream> 

using namespace std; 

int TestIntReturn(int &x, int &y) 
{ 
    x = 1000; 
    y = 1000; 
    return x+y; 
} 

int main() 
{ 
    int a = 1; 
    int b = 2; 
    cout << a << " " << b << endl; 
    TestIntReturn(a,b); 
    cout << a << " " << b << endl; 
} 

क्या TestInReturn(a,b) के रिटर्न मान पर होता है के बाद से यह अप्रयुक्त है?

+0

आपके प्रश्न का उत्तर नहीं है, लेकिन शैली के मामले के बारे में, आप 'नेमस्पेस std' का उपयोग करके अपने उपयोग पर पुनर्विचार करना चाहेंगे। क्यों, कृपया सी ++ एफएक्यू एंट्री एंट्री पढ़ें [क्या मुझे अपने कोड में 'नेमस्पेस एसडीडी' का उपयोग करना चाहिए?] (Http://www.parashift.com/c++-faq-lite/using-namespace-std.html) – DavidRR

उत्तर

8

यह को त्याग दिया गया है; अभिव्यक्ति TestInReturn(a,b) एक त्याग-मूल्य अभिव्यक्ति है। int को छोड़कर कोई प्रभाव नहीं पड़ता है, लेकिन volatile int (या कोई अन्य अस्थिर-योग्य प्रकार) को छोड़कर स्मृति से पढ़ने का प्रभाव हो सकता है।

+0

यह कैसे हो सकता है? फ़ंक्शन का रिटर्न वैल्यू एक रावल्यू है, जिसका अर्थ है कि इसमें सीवी-क्वालीफिकेशन नहीं है --- किसी भी 'अस्थिर' (या 'कॉन्स्ट') को अनदेखा किया जाता है (जब तक कि यह क्लास प्रकार न हो)। –

+0

@JamesKanze हां, और फ़ंक्शन कॉल भी 5p11 में lvalue-to-rvalue रूपांतरण के कारण अभिव्यक्तियों में से एक नहीं है। मैं सामान्य रूप से त्याग-मूल्य अभिव्यक्तियों के बारे में बात कर रहा था। – ecatmur

+0

मुझे पता है कि एक समय में, सी मानकों समिति में इस बारे में कुछ चर्चा हुई थी: 'int volatile i; i; ', दूसरे कथन में कोई पहुंच है। मुझे नहीं पता कि अंतिम आम सहमति क्या थी, लेकिन एक प्राथमिकता, मैं नहीं कहूंगा। –

4

वापसी मूल्य बस त्याग दिया जाता है। सटीक परिदृश्य के आधार पर ऑप्टिमाइज़र पूरे फंक्शन कॉल को ऑप्टिमाइज़ करने का निर्णय ले सकता है यदि कोई अवलोकन दुष्प्रभाव नहीं है (जो आपके उदाहरण में नहीं है)।

तो, TestIntReturn से वापस लौटने पर, फ़ंक्शन स्टैक पर वापसी मूल्य को धक्का देगा, फिर कॉलर तदनुसार स्टैक फ्रेम को समायोजित करेगा, लेकिन बदले गए मान को किसी भी चर में स्टैक से कॉपी नहीं करेगा।

+0

चालू वापसी मूल्य के रूप में 'int' क्या वास्तुकला ढेर पर होगा? इंटेल पर, यह 'ईएक्स' में होगा; 'o0' में एक स्पार्क पर। कोड सिर्फ रजिस्टर की सामग्री को अनदेखा कर देगा। –

0

कुछ भी नहीं - यह ईथर में जाता है, और संग्रहीत/उपयोग नहीं किया जाता है। वापसी मूल्य खुद ही एक रावल या अस्थायी है; मेरा मानना ​​है कि संकलक वास्तव में उपयोग नहीं किए जाने के कारण भी अस्थायी सृजन को अनुकूलित करेगा।

+0

औपचारिक अर्थशास्त्र यह है कि पूर्ण अभिव्यक्ति के अंत में अस्थायी रूप से नष्ट हो जाता है। चूंकि फ़ंक्शन के अंदर अस्थायी _constructed_ है, और कॉल साइट पर _destructed_ है, तो कंपाइलर को अस्थायी को खत्म करने के लिए फ़ंक्शन को इनलाइन करना होगा। –

0

वापसी मूल्य स्टैक पर संग्रहीत किया जाता है और फ़ंक्शन लौटने पर पॉप-अप हो जाता है। चूंकि इसे कॉलर द्वारा एक चर के लिए असाइन नहीं किया जा रहा है, इसलिए स्टैक पॉप होने पर इसे हटा दिया जाता है।

+0

बहुत कम आर्किटेक्चर स्टैक पर रिटर्न वैल्यू स्टोर करेंगे, कम से कम अगर यह टाइप 'int' है। –

11

चूंकि आप विंडोज के बारे में बात कर रहे हैं, हम एक x86 प्रोसेसर मान लेंगे।

इस मामले में, वापसी मूल्य आम तौर पर रजिस्टर ईएक्स में होगा। चूंकि आप इसका उपयोग नहीं कर रहे हैं, इसलिए उस मूल्य को केवल अनदेखा कर दिया जाएगा, और अगली बार ईएक्स निष्पादन में कुछ लिखने के लिए कुछ कोड ओवरराइट किया जाएगा।

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

आपके मामले में, फ़ंक्शन के कुछ दुष्प्रभाव होते हैं, इसलिए इसे उन दुष्प्रभावों को पूरा करना होता है, लेकिन योग की गणना करने के लिए कोड को अच्छी तरह से बढ़ाया जा सकता है। यहां तक ​​कि अगर यह elided नहीं था, यह शायद यह पता लगा सकता है कि जो जोड़ा जा रहा है वास्तव में दो स्थिरांक हैं, इसलिए यह किसी भी मामले में रन-टाइम पर परिणाम की वास्तविक गणना नहीं करेगा, बस mov EAX, 2000 जैसे कुछ ऐसा करने के लिए प्रतिलाभ की मात्रा।

0

सभी ने सही उत्तर दिया - इस मामले में वापसी मूल्य को त्याग दिया गया है, और इस विशिष्ट उदाहरण में, आप इसे अनदेखा कर सकते हैं।

हालांकि, अगर वापसी मान समारोह के अंदर आबंटित स्मृति के लिए सूचक है, और आप इसे अनदेखा, आप एक memory leak.

तो कुछ समारोह को महत्व देता है तो आप सिर्फ नजरअंदाज नहीं कर सकते है, लेकिन में यह मामला - आप कर सकते हैं।

+0

ऑब्जेक्ट की ओर इशारा करते हुए, आप इसे अनदेखा कर सकते हैं। मैंने उन ऑब्जेक्ट्स का उपयोग किया है जिनके कन्स्ट्रक्टर ऑब्जेक्ट को एक शब्दकोश में पंजीकृत करता है, जहां इसे बाद में पाया जा सकता है। दूसरी ओर, यदि वापसी मूल्य एक स्मार्ट सूचक, या किसी अन्य वर्ग प्रकार है, तो इसके विनाशक को बुलाया जाएगा। –

0

आदिम प्रकारों के मामले में, कुछ भी नहीं होता है। यह अभी अनदेखा है। कक्षा के प्रकार के मामले में, लौटाई गई वस्तु नष्ट हो जाएगी, इसके बिना कुछ भी हो रहा है।

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