इसका उत्तर है: यह इस बात पर निर्भर करता है कि आप किस C ++ मानक का विरोध कर रहे हैं। इस पंक्ति के अपवाद के साथ सभी कोड सभी मानकों पर पूरी तरह से सुव्यवस्थित हैं:
char * s = "My String";
अब, स्ट्रिंग शाब्दिक प्रकार है const char[10]
और हम इसे एक नॉन-कास्ट पॉइंटर को इनिशियलाइज़ करने की कोशिश कर रहे हैं। char
स्ट्रिंग शाब्दिक के परिवार के अलावा अन्य सभी प्रकारों के लिए , इस तरह की शुरूआत हमेशा अवैध थी। उदाहरण के लिए:
const int arr[] = {1};
int *p = arr; // nope!
हालांकि, स्ट्रिंग सीडल्स के लिए प्री-सी ++ 11 में, /4.2 / 2 में एक अपवाद था:
एक स्ट्रिंग शाब्दिक (2.13.4) है कि एक विस्तृत स्ट्रिंग शाब्दिक प्रकार के "एक rvalue में बदला जा सकता नहीं चार सूचक "; [...]। किसी भी स्थिति में, परिणाम सरणी के पहले तत्व के लिए एक संकेतक है। यह रूपांतरण केवल तब माना जाता है जब एक स्पष्ट उपयुक्त सूचक लक्ष्य प्रकार होता है, न कि तब जब एक अंतराल से एक अंतराल में परिवर्तित होने की सामान्य आवश्यकता होती है। [नोट: यह रूपांतरण पदावनत है । देखें अनुलग्नक डी। ]
इसलिए सी ++ 03 में, कोड पूरी तरह से ठीक है (हालांकि पदावनत), और इसमें स्पष्ट, पूर्वानुमानित व्यवहार है।
C ++ 11 में, वह ब्लॉक मौजूद नहीं है - स्ट्रिंग शाब्दिकों में रूपांतरित होने के लिए ऐसा कोई अपवाद नहीं है char*
, और इसलिए कोड केवल int*
उदाहरण के रूप में मेरे द्वारा प्रदत्त उदाहरण के रूप में बीमार है । कंपाइलर को डायग्नोस्टिक जारी करने के लिए बाध्य किया जाता है, और आदर्श रूप से इस तरह के मामलों में जो C ++ टाइप सिस्टम के स्पष्ट उल्लंघन हैं, हम एक अच्छे कंपाइलर से इस संबंध में न केवल पुष्टि करने की अपेक्षा करेंगे (जैसे कि चेतावनी जारी करके) एकमुश्त।
कोड को आदर्श रूप से संकलित नहीं किया जाना चाहिए - लेकिन जीसीसी और क्लैंग दोनों पर होता है (मुझे लगता है क्योंकि शायद वहाँ बहुत सारे कोड हैं जो थोड़े से लाभ के साथ टूट जाएंगे, इस प्रकार के सिस्टम छेद एक दशक से अधिक के लिए पदावनत होने के बावजूद)। कोड बीमार है, और इस प्रकार यह इस कारण से समझ में नहीं आता है कि कोड का व्यवहार क्या हो सकता है। लेकिन इस विशिष्ट मामले और इसके इतिहास को पहले अनुमति दिए जाने को देखते हुए, मैं इसके परिणामस्वरूप कोड की व्याख्या करने के लिए एक अनुचित खिंचाव नहीं मानता, जैसे कि यह एक अंतर्निहित const_cast
, कुछ इस तरह था:
const int arr[] = {1};
int *p = const_cast<int*>(arr); // OK, technically
इसके साथ, बाकी कार्यक्रम पूरी तरह से ठीक है, जैसा कि आप वास्तव में s
फिर कभी नहीं छूते हैं । गैर- पॉइंटर के माध्यम से बनाई गई वस्तु को पढ़ना पूरी तरह से ठीक है। इस तरह के पॉइंटर के माध्यम से निर्मित वस्तु को लिखना अपरिभाषित व्यवहार है:const
const
const
std::cout << *p; // fine, prints 1
*p = 5; // will compile, but undefined behavior, which
// certainly qualifies as "unpredictable"
जैसा कि s
आपके कोड में कहीं से भी कोई संशोधन नहीं है , प्रोग्राम C ++ 03 में ठीक है, C ++ 11 में संकलित करने में विफल होना चाहिए, लेकिन वैसे भी - और यह देखते हुए कि संकलक इसे अनुमति देते हैं, इसमें अभी भी कोई अपरिभाषित व्यवहार नहीं है ification । भत्ते के साथ कि कंपाइलर अभी भी [गलत तरीके से] C ++ 03 नियमों की व्याख्या कर रहे हैं, मुझे ऐसा कुछ भी नहीं दिख रहा है जिससे "अप्रत्याशित" व्यवहार हो। s
हालांकि लिखें , और सभी दांव बंद हैं। C ++ 03 और C ++ 11 दोनों में।
† हालांकि, फिर से, परिभाषा के अनुसार बीमार-निर्मित कोड से उचित व्यवहार की कोई उम्मीद
नहीं है, सिवाय इसके कि, मैट मैकनब के उत्तर को न देखें