दोनों (a)
और (b)
अपरिभाषित व्यवहार में परिणाम। अशक्त सूचक के माध्यम से सदस्य फ़ंक्शन को कॉल करने के लिए हमेशा अपरिभाषित व्यवहार होता है। यदि फ़ंक्शन स्थिर है, तो यह तकनीकी रूप से भी अपरिभाषित है, लेकिन कुछ विवाद है।
समझने वाली पहली बात यह है कि अशक्त सूचक को निष्क्रिय करने के लिए अपरिभाषित व्यवहार क्यों है। C ++ 03 में, वास्तव में यहाँ थोड़ी अस्पष्टता है।
यद्यपि "अपरिभाषित व्यवहार में अशक्त सूचक परिणाम" का उल्लेख encing1.9 / 4 और /8.3.2 / 4 दोनों में नोटों में किया गया है, यह स्पष्ट रूप से कभी नहीं कहा गया है। (नोट गैर-मानक हैं।)
हालाँकि, कोई इसे /3.10 / 2 से घटाने का प्रयास कर सकता है:
एक अंतराल एक वस्तु या कार्य को संदर्भित करता है।
जब dereferencing, परिणाम एक अंतराल है। एक अशक्त सूचक एक वस्तु को संदर्भित नहीं करता है , इसलिए जब हम उस अंतराल का उपयोग करते हैं तो हमारे पास अपरिभाषित व्यवहार होता है। समस्या यह है कि पिछले वाक्य को कभी नहीं कहा गया है, इसलिए इसका क्या अर्थ है "अंतराल" का उपयोग करना? यहां तक कि इसे बिल्कुल भी उत्पन्न करते हैं, या इसका उपयोग करने के लिए और अधिक औपचारिक अर्थों में उपयोग करना है?
भले ही, यह निश्चित रूप से एक प्रतिद्वंद्विता में परिवर्तित नहीं किया जा सकता (/4.1 / 1):
यदि जिस वस्तु से लैवल्यू संदर्भित होता है, वह प्रकार T की वस्तु नहीं है और T से प्राप्त प्रकार की वस्तु नहीं है, या यदि वस्तु असिंचित है, तो इस रूपांतरण की आवश्यकता वाले प्रोग्राम में अपरिभाषित व्यवहार होता है।
यहाँ यह निश्चित रूप से अपरिभाषित व्यवहार है।
अस्पष्टता यह है कि यह अपरिभाषित व्यवहार करने के लिए है या नहीं, लेकिन यह अमान्य सूचक से मान का उपयोग नहीं है (अर्थात, एक अंतराल प्राप्त करें, लेकिन इसे एक प्रतिद्वंद्विता में परिवर्तित न करें)। यदि नहीं, तो int *i = 0; *i; &(*i);
अच्छी तरह से परिभाषित है। यह एक सक्रिय मुद्दा है ।
तो हमारे पास एक सख्त "डेरेक्शन ऑफ़ ए नल पॉइंटर है, अपरिभाषित व्यवहार प्राप्त करें" दृश्य और एक कमजोर "एक डिरेल्ड नेल पॉइंटर का उपयोग करें, अपरिभाषित व्यवहार प्राप्त करें" दृश्य।
अब हम इस प्रश्न पर विचार करते हैं।
हां, (a)
अपरिभाषित व्यवहार का परिणाम है। वास्तव में, यदि this
शून्य है तो फ़ंक्शन की सामग्री की परवाह किए बिना परिणाम अपरिभाषित है।
यह follows5.2.5 / 3 से इस प्रकार है:
यदि E1
टाइप "पॉइंटर टू क्लास एक्स" है, तो अभिव्यक्ति E1->E2
को समकक्ष रूप में बदल दिया जाता है(*(E1)).E2;
*(E1)
एक सख्त व्याख्या के साथ अपरिभाषित व्यवहार का परिणाम देगा, और .E2
इसे एक प्रतिद्वंद्विता में परिवर्तित करता है, जिससे यह कमजोर व्याख्या के लिए अपरिभाषित व्यवहार करता है।
यह इस प्रकार भी है कि यह सीधे से अपरिभाषित व्यवहार है (.19.3.1 / 1):
यदि किसी वर्ग X के गैर-स्थैतिक सदस्य फ़ंक्शन को किसी ऑब्जेक्ट के लिए कहा जाता है जो कि X का नहीं है, या X से प्राप्त एक प्रकार का है, तो व्यवहार अपरिभाषित है।
स्थिर कार्यों के साथ, सख्त बनाम कमजोर व्याख्या अंतर बनाती है। कड़ाई से बोलते हुए, यह अपरिभाषित है:
क्लास सदस्य एक्सेस सिंटैक्स का उपयोग करके एक स्थिर सदस्य को संदर्भित किया जा सकता है, जिस स्थिति में ऑब्जेक्ट-एक्सप्रेशन का मूल्यांकन किया जाता है।
यही है, यह मूल्यांकन किया जाता है जैसे कि यह गैर-स्थैतिक थे और हम एक बार फिर से एक अशक्त सूचक को निष्क्रिय कर देते हैं (*(E1)).E2
।
हालाँकि, क्योंकि E1
स्थैतिक सदस्य-फ़ंक्शन कॉल में उपयोग नहीं किया जाता है, यदि हम कमजोर व्याख्या का उपयोग करते हैं तो कॉल अच्छी तरह से परिभाषित है। *(E1)
एक परिणाम में, स्थैतिक कार्य हल हो जाता है, *(E1)
त्याग दिया जाता है, और फ़ंक्शन को कहा जाता है। वहाँ कोई अंतराल-से-अंतराल परिवर्तन नहीं है, इसलिए कोई अपरिभाषित व्यवहार नहीं है।
C ++ 0x में, n3126 के रूप में, अस्पष्टता बनी हुई है। अभी के लिए, सुरक्षित रहें: सख्त व्याख्या का उपयोग करें।