19

मैं हाल ही में निम्न स्थिति भर में भाग गया:मूल्यांकन आदेश

#include <iostream> 

int *p = 0; 

int f() { 
    p = new int(10); 
    return 0; 
} 

void g(int x, int *y = p) { 
    std::cout << y << std::endl; 
} 

int main() { 
    g(f()); 
} 

यह काफी सूक्ष्म है के बाद से आप आमतौर पर डिफ़ॉल्ट तर्क समारोह कॉल के लिए उनके मूल्यांकन के दौरान बदल की उम्मीद नहीं करते । मुझे इस त्रुटि को देखने के लिए असेंबली को देखना पड़ा।

अब मेरा प्रश्न है: क्या यह वास्तव में अपरिभाषित व्यवहार है, क्योंकि फ़ंक्शन तर्कों के मूल्यांकन आदेश से संबंधित कोई गारंटी नहीं है?

उत्तर

15

फ़ंक्शन तर्कों के मूल्यांकन (यानी मान निर्धारित करना) का क्रम निर्दिष्ट नहीं है। कंपाइलर किसी भी क्रम में उन्हें निष्पादित करने के लिए स्वतंत्र है, और यहां तक ​​कि अगर ऐसा करने से रोकने के लिए कोई अन्य कारक नहीं है तो भी अंतःस्थापित हो जाता है।

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

+0

"कॉलर के संदर्भ में डिफ़ॉल्ट तर्कों का मूल्यांकन होता है" क्या आपके पास इस दावे के लिए वर्तमान सी ++ मानक में कोई संदर्भ है? – phlipsy

+1

1.9p11 में एक गैर-मानक नोट है जो स्पष्ट रूप से कहता है। इसके अलावा, मुझे लगता है कि यह केवल अन्य तर्कों से भेदभाव की कमी से निहित है। –

+2

@phlipsy देखें [dcl.fct.default]/9 "प्रत्येक बार फ़ंक्शन कहलाए जाने पर डिफ़ॉल्ट तर्कों का मूल्यांकन किया जाता है। फ़ंक्शन तर्कों का मूल्यांकन अनिश्चित है।", मुझे लगता है कि यह स्पष्ट रूप से इंगित करता है कि 'g (f()) '' जी (एफ(), पी) के समान है –

13

अगर मैं इसे सही ढंग से समझते हैं, अपने कॉल

g(f()); 

घोषणा

void g(int x, int *y = p); 

और g कार्य करने के लिए तर्क, f() और p के कारण

g(f(), p); 

के बराबर है , किसी भी क्रम में मूल्यांकन किया जा सकता है, तो आप 01 प्राप्त कर सकते हैंy के साथ बुलाया गया शून्य या तो असाइन किया गया है (यदि p का मूल्यांकन पहले किया जाता है, तो यह अपना प्रारंभिक मान देता है) या नए आवंटित सरणी सूचक (यदि f() का मूल्यांकन पहले किया जाता है और यह p को इसके दुष्प्रभाव के रूप में एक नया मान निर्दिष्ट करता है)।

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