सबसे सख्त अर्थों में, यह अपरिभाषित व्यवहार नहीं है, बल्कि कार्यान्वयन-परिभाषित है। इसलिए, हालांकि यदि आप गैर-मुख्यधारा के आर्किटेक्चर का समर्थन करने की योजना बना रहे हैं, तो आप शायद ऐसा कर सकते हैं।
अंतरजाल द्वारा दिया गया मानक उद्धरण एक अच्छा है, जो यूबी को दर्शाता है, लेकिन यह मेरी राय में केवल दूसरी सबसे अच्छी हिट है, क्योंकि यह सूचक-सूचक अंकगणितीय (मजेदार रूप से, एक स्पष्ट रूप से यूबी है, जबकि दूसरा नहीं है)। सीधे सवाल में ऑपरेशन के साथ एक पैराग्राफ है:
[expr.post.incr] / [expr.pre.incr]
ऑपरेंड पूरी तरह से परिभाषित ऑब्जेक्ट प्रकार के लिए [...] या एक सूचक होगा।
ओह, एक पल रुको, एक पूरी तरह से परिभाषित वस्तु प्रकार? बस इतना ही? मेरा मतलब है, वास्तव में, टाइप करें ? तो आपको किसी वस्तु की आवश्यकता नहीं है?
वास्तव में एक संकेत खोजने के लिए पढ़ने में काफी थोड़ा समय लगता है कि वहां कुछ ऐसा नहीं है जो बहुत अच्छी तरह से परिभाषित हो। क्योंकि अब तक, यह पढ़ता है जैसे कि आप इसे पूरी तरह से करने की अनुमति देते हैं, कोई प्रतिबंध नहीं।
[basic.compound] 3
एक सूचक किस प्रकार का हो सकता है, इस बारे में एक बयान देता है, और अन्य तीन में से कोई भी नहीं होने के कारण, आपके ऑपरेशन का परिणाम स्पष्ट रूप से 3.4 के तहत गिर जाएगा: अमान्य सूचक ।
हालांकि यह नहीं कहता है कि आपको अमान्य सूचक रखने की अनुमति नहीं है। इसके विपरीत, यह कुछ बहुत ही सामान्य, सामान्य स्थितियों (जैसे भंडारण अवधि का अंत) को सूचीबद्ध करता है जहां संकेत नियमित रूप से अमान्य हो जाते हैं। तो यह स्पष्ट रूप से एक स्वीकार्य बात है। और सचमुच में:
[basic.stc] 4
एक अवैध पॉइंटर मान के माध्यम से अप्रत्यक्ष और एक अमान्य सूचक को एक डिक्लेरेशन फ़ंक्शन में पास करने से अपरिभाषित व्यवहार होता है। अमान्य पॉइंटर मान के किसी अन्य उपयोग में कार्यान्वयन-परिभाषित व्यवहार होता है।
हम वहां "कोई अन्य" कर रहे हैं, इसलिए यह अपरिभाषित व्यवहार नहीं है, लेकिन कार्यान्वयन-परिभाषित है, इस प्रकार आम तौर पर स्वीकार्य है (जब तक कि कार्यान्वयन स्पष्ट रूप से कुछ अलग नहीं कहता है)।
दुर्भाग्य से, यह कहानी का अंत नहीं है। हालांकि शुद्ध परिणाम यहाँ से किसी भी अधिक नहीं बदलता है, यह अधिक भ्रमित हो जाता है, अब आप "पॉइंटर" के लिए खोज करते हैं:
[basic.compound]
ऑब्जेक्ट पॉइंटर प्रकार का एक मान्य मान मेमोरी में बाइट या अशक्त पॉइंटर के पते को दर्शाता है । यदि टाइप ए की एक वस्तु एक पते पर स्थित है [...] तो उस वस्तु को इंगित करने के लिए कहा जाता है, भले ही मूल्य कैसे प्राप्त किया गया हो ।
[नोट: उदाहरण के लिए, एक सरणी के अंत में पिछले एक पते को उस सरणी के तत्व प्रकार के असंबंधित ऑब्जेक्ट को इंगित करने के लिए माना जाएगा जो उस पते पर स्थित हो सकता है। [...]]।
पढ़ें: ठीक है, कौन परवाह करता है! जब तक कोई पॉइंटर मेमोरी में कहीं इंगित करता है , मैं अच्छा हूं?
[basic.stc.dynamic.safety] एक पॉइंटर मान एक सुरक्षित रूप से व्युत्पन्न पॉइंटर [ब्ला ब्ला] है
के रूप में पढ़ें: ठीक है, सुरक्षित रूप से व्युत्पन्न, जो भी हो। यह नहीं समझाता है कि यह क्या है, और न ही यह कहता है कि मुझे वास्तव में इसकी आवश्यकता है। सुरक्षित रूप से व्युत्पन्न-बिल्ली। जाहिरा तौर पर मैं अभी भी गैर-सुरक्षित-व्युत्पन्न संकेत बस ठीक कर सकता हूं। मैं यह अनुमान लगा रहा हूँ कि शायद उन्हें ऐसा करने का कोई अच्छा विचार नहीं होगा, लेकिन यह उनके लिए पूरी तरह से स्वीकार्य है। यह अन्यथा नहीं कहता है।
एक कार्यान्वयन में आराम सूचक सुरक्षा हो सकती है, जिस स्थिति में सूचक मान की वैधता इस बात पर निर्भर नहीं करती है कि यह सुरक्षित रूप से व्युत्पन्न सूचक मान है या नहीं।
ओह, तो यह बात नहीं हो सकती है, बस मैंने जो सोचा था। लेकिन रुकिए ... "हो सकता है" नहीं? इसका मतलब है, यह भी हो सकता है । मुझे कैसे पता चलेगा?
वैकल्पिक रूप से, एक कार्यान्वयन में सख्त पॉइंटर सुरक्षा हो सकती है, उस स्थिति में एक पॉइंटर मान जो कि सुरक्षित रूप से व्युत्पन्न पॉइंटर मान नहीं है, एक अमान्य पॉइंटर मान है जब तक कि संदर्भित पूरी वस्तु गतिशील भंडारण अवधि की न हो और पहले से पहुंच से बाहर घोषित की गई हो।
रुको, तो यह भी संभव है कि मुझे declare_reachable()
हर सूचक पर कॉल करने की आवश्यकता है ? मुझे कैसे पता चलेगा?
अब, आप intptr_t
एक सुरक्षित रूप से व्युत्पन्न पॉइंटर का पूर्णांक प्रतिनिधित्व देते हुए, जिसे अच्छी तरह से परिभाषित किया गया है , में परिवर्तित कर सकते हैं । जिसके लिए, बेशक, पूर्णांक होने के नाते, यह पूरी तरह से वैध और अच्छी तरह से परिभाषित है जैसा कि आप चाहते हैं।
और हां, आप intptr_t
बैक को एक पॉइंटर में बदल सकते हैं , जो अच्छी तरह से परिभाषित भी है। केवल, मूल मूल्य नहीं होने के कारण, यह अब गारंटी नहीं है कि आपके पास सुरक्षित रूप से व्युत्पन्न सूचक (स्पष्ट रूप से) है। फिर भी, सभी में, मानक के अक्षर तक, कार्यान्वयन-परिभाषित होने के दौरान, यह करने के लिए एक 100% वैध बात है:
[expr.reinterpret.cast] 5
इंटीग्रल टाइप या एन्यूमरेशन टाइप का मान स्पष्ट रूप से पॉइंटर में बदला जा सकता है। एक पॉइंटर पर्याप्त आकार के पूर्णांक में परिवर्तित हो जाता है [...] और उसी पॉइंटर प्रकार पर वापस जाता है [...] मूल मूल्य; संकेत और पूर्णांक के बीच मैपिंग अन्यथा कार्यान्वयन-परिभाषित हैं।
कैच
पॉइंटर्स केवल साधारण पूर्णांक हैं, केवल आप उन्हें पॉइंटर्स के रूप में उपयोग करने के लिए होते हैं। ओह अगर केवल यह सच था!
दुर्भाग्य से, ऐसे आर्किटेक्चर मौजूद हैं जहां यह बिल्कुल सच नहीं है, और केवल एक अमान्य पॉइंटर उत्पन्न करना (इसे डीरफ्रेंसिंग नहीं करना है, बस इसे पॉइंटर रजिस्टर में रखना) एक जाल का कारण होगा।
तो यह "कार्यान्वयन परिभाषित" का आधार है। यही कारण है कि, और यह तथ्य एक सूचक incrementing है कि जब भी आप चाहते हैं, जैसा कि आप कृपया कर सकते थे पाठ्यक्रम कारण अतिप्रवाह, जो मानक से निपटने के लिए नहीं चाहता है की। अनुप्रयोग पता स्थान का अंत अतिप्रवाह के स्थान के साथ मेल नहीं खा सकता है, और आपको यह भी नहीं पता है कि किसी विशेष वास्तुकला पर संकेत के लिए अतिप्रवाह जैसी कोई चीज है या नहीं। सभी सभी में यह एक बुरे सपने है संभावित लाभों के किसी भी संबंध में नहीं।
दूसरी तरफ एक-अतीत की वस्तु स्थिति से निपटना आसान है: कार्यान्वयन को बस यह सुनिश्चित करना चाहिए कि कोई वस्तु कभी आवंटित न हो इसलिए पता स्थान में अंतिम बाइट पर कब्जा है। इसलिए यह अच्छी तरह से परिभाषित है क्योंकि यह गारंटी के लिए उपयोगी और तुच्छ है।