2015-06-10 3 views
6

कुछ पॉइंटर कास्ट का परिणाम अनिर्दिष्ट के रूप में वर्णित है। उदाहरण के लिए, [expr.static.cast]/13:सी ++ 14 में एक निर्दिष्ट पॉइंटर रूपांतरण कैसे व्यवहार करता है?

प्रकार के "CV1 शून्य करने के लिए सूचक" एक prvalue प्रकार का एक prvalue करने के लिए "सूचक CV2 टी करने के लिए," परिवर्तित किया जा सकता [...] तो मूल सूचक मूल्य स्मृति में एक बाइट के पते ए का प्रतिनिधित्व करता है और ए टी की संरेखण आवश्यकता को पूरा करता है, जिसके परिणामस्वरूप सूचक सूचक मूल सूचक मान के समान पते का प्रतिनिधित्व करता है, यानी ए किसी अन्य ऐसे सूचक का परिणाम रूपांतरण निर्दिष्ट नहीं है।

मेरे सवाल यह है: इस मामले में जहां संरेखण नहीं संतुष्ट है में, क्या संभव परिणाम कर रहे हैं?

उदाहरण के लिए, निम्नलिखित परिणाम अनुमत हैं?

  • एक अशक्त सूचक
  • गलत सूचक मूल्य (यानी सूचक जो आकार T की आवंटित भंडारण को इंगित नहीं करता है)
  • स्मृति का एक पूरी तरह से अलग हिस्से में एक T के लिए एक वैध सूचक
संदर्भ के लिए

कोड का नमूना:

#include <iostream> 

int main(int argc, char **argv) 
{ 
    int *b = (int *)"Hello, world"; // (1) 

    *b = -1;       // (2) 
    std::cout << argc << '\n'; 
} 

लाइन (1) [expr.static.cast] से/13 मेरी उपर्युक्त उद्धरण से चलाता है, क्योंकि यह एक reinterpret_cast जो [expr.reinterpret.cast]/7 जो void * के माध्यम से ing static_cast के मामले में रूपांतरण को परिभाषित करता है द्वारा कवर किया जाता है।

यदि अनिर्दिष्ट परिणाम एक अमान्य सूचक मान हो सकता है, तो लाइन (1) हार्डवेयर जाल का कारण बन सकती है। (संदर्भ: N4430 जो समान शब्द को स्पष्ट करता है जो सी ++ 14 और सी ++ 11 में था)।

उपप्रमेय प्रश्न: वहाँ किसी भी मामले में जो लाइन में 1 अपरिभाषित व्यवहार का कारण होता है? (मुझे इस चरण में ऐसा नहीं लगता है, क्योंकि सी ++ 14 अमान्य सूचक मूल्य पढ़ने कार्यान्वयन-परिभाषित या हार्डवेयर जाल का कारण बनता है)।


भी दिलचस्प है कि लाइन (2) ज्यादातर मामलों में सख्त अलियासिंग उल्लंघन (और शायद भी अन्य कारणों) की वजह से व्यवहार अपरिभाषित किया जाएगा लेकिन यदि अनिर्दिष्ट परिणाम &argc तो इस कार्यक्रम हो सकता है कर सकते थे अपरिभाषित ट्रिगर किए बिना उत्पादन -1 व्यवहार!

+6

अरे उपयोग करने के लिए है, यह है अनिर्दिष्ट। – EJP

+1

"... तो यह प्रोग्राम अपरिभाषित व्यवहार को ट्रिगर किए बिना' -1' आउटपुट कर सकता है "एक अजीब बात है - और मैं इसे वाक्यांश के गलत तरीके से कहूंगा। रेखा (2) हमेशा अपरिभाषित व्यवहार में परिणाम। "अपरिभाषित व्यवहार" का अर्थ यह है कि प्रोग्राम का कोई भी व्यवहार जो भी spec का पालन करेगा, जिसमें आउटपुट -1 के व्यवहार शामिल हैं। एक "अनिर्दिष्ट मूल्य" एक मान (व्यवहार नहीं) है कि spec बाधा नहीं है और कार्यान्वयन दस्तावेज़ की आवश्यकता नहीं है। – Nemo

+0

@Nemo यूबी में लाइन 2 परिणाम कैसे होता है (यदि 'बी' के पास मूल्य 'और argc' है) –

उत्तर

3

मेरा प्रश्न है: यदि संरेखण संतुष्ट नहीं है, तो संभावित परिणाम क्या हैं?

जहां तक ​​मैं N4303: Pointer safety and placement new बता सकता हूं आंशिक रूप से इस प्रश्न का उत्तर देता हूं, हालांकि कुछ हद तक परोक्ष रूप से। यह पेपर CWG issue 1412: Problems in specifying pointer conversions को संदर्भित करता है जो में परिवर्तन लाता है [expr.static।डाली]/13 है कि आप संदर्भ, विशेष रूप से जोड़ने:

[...] मूल सूचक मूल्य स्मृति में एक बाइट और एक को संतुष्ट करता है टी के संरेखण आवश्यकता का पता एक का प्रतिनिधित्व करता है, तो जिसके परिणामस्वरूप सूचक मूल्य, कि है, मूल सूचक मूल्य के रूप में एक ही पते का प्रतिनिधित्व करता है ए किसी अन्य तरह के सूचक रूपांतरण के परिणाम अनिर्दिष्ट है। [...]

इस परिवर्तन N4303 के संदर्भ में कहते हैं (जोर मेरा):

डीआर 1412 [सीडब्ल्यूजी 1412] के लिए संकल्प को अपनाने से पहले, बीपी का मूल्य इसकी प्रारंभिक बिंदु के आधार पर निर्दिष्ट नहीं है और इसके बाद ऑपरेटर को नई अभिव्यक्ति के माध्यम से नया पास कर दिया गया है। ने कहा कि पॉइंटर शून्य, अपर्याप्त रूप से गठबंधन या अन्यथा उपयोग करने के लिए खतरनाक हो सकता है।

तो एक अनिर्दिष्ट रूपांतरण में बदल सकते हैं:

  • एक नल पॉइंटर
  • एक अपर्याप्त गठबंधन सूचक
  • एक संकेतक है कि खतरनाक है
+0

"एक सूचक जो उपयोग करने के लिए खतरनाक है" काफी हद तक लगता है। "अमान्य सूचक मूल्य" निश्चित रूप से एक सूचक है जो उपयोग करने के लिए खतरनाक है; वहां अन्य संभावनाएं क्या हैं? –

+0

"अपर्याप्त रूप से गठबंधन सूचक" - जहां तक ​​मैं देख सकता हूं कि सख्त एलियासिंग नियम के अलावा कोई अन्य पाठ नहीं है, जो इस तरह के सूचक का उपयोग किया जा रहा है। केवल इस खंड में हम संभावित रूप से ऐसे पॉइंटर को पहले स्थान पर बनाए रखने से रोकने के लिए चर्चा कर रहे हैं। तो, संभवतः, हार्डवेयर संरेखण को लागू करने वाली मशीनों पर वे अपर्याप्त रूप से गठबंधन सूचक नहीं लौट सके। –

+0

@MattMcNabb: बस कुछ अन्य संभावनाओं का नाम देने के लिए: एक सूचक जो स्वयं के बराबर तुलना नहीं करता है, या एक सूचक जिसके लिए पॉइंटर अंकगणितीय ब्रेक (यानी पी + 1-1! = पी) – MSalters

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