C में स्ट्रिंग से निरंतर रूपांतरण 'char *' में क्यों मान्य है लेकिन C ++ में अमान्य है


163

सी ++ 11 मानक (आईएसओ / आईईसी 14882: 2011) में कहते हैं § C.1.1:

char* p = "abc"; // valid in C, invalid in C++

C ++ के लिए यह स्ट्रिंग के लिटर के लिए एक संकेतक के रूप में ठीक है हानिकारक है क्योंकि इसे संशोधित करने का कोई भी प्रयास दुर्घटना की ओर जाता है। लेकिन यह C में मान्य क्यों है?

C ++ 11 भी कहता है:

char* p = (char*)"abc"; // OK: cast added

जिसका मतलब है कि अगर किसी कलाकार को पहले बयान में जोड़ा जाता है तो वह वैध हो जाता है।

कास्टिंग C ++ में दूसरा स्टेटमेंट मान्य क्यों करता है और यह पहले वाले से अलग कैसे है? क्या यह अभी भी हानिकारक नहीं है? यदि यह मामला है, तो मानक ने क्यों कहा कि यह ठीक है?


3
C ++ 11 पहले वाले को अनुमति नहीं देता है। मुझे पता नहीं क्यों सी एक स्ट्रिंग शाब्दिक के प्रकार बनाया है char[]पहली जगह में। दूसरा एक const_castभेस में है।
क्रिस

4
बस बहुत सी विरासत सी कोड है जो इस नियम को बदल दिए जाने पर टूट जाएगा।
पॉल आर

1
कृपया पाठ को उद्धृत करें जहां मानक कहता है कि दूसरा है OK
नवाज

13
सी लैंग्वेज में पहले से ही स्ट्रगल था const, इसलिए वे जरूरी नहीं थे const
केसी

2
C और C ++ आपको लगभग किसी भी प्रकार से दूसरे प्रकार तक कास्ट करने की अनुमति देता है। इसका मतलब यह नहीं है कि ये जातियां सार्थक और सुरक्षित हैं।
सियान रेन

जवाबों:


207

C ++ 03 के माध्यम से, आपका पहला उदाहरण मान्य था, लेकिन एक अविकसित अंतर्निहित रूपांतरण का उपयोग किया गया - एक स्ट्रिंग शाब्दिक को प्रकार के होने के रूप में माना जाना चाहिए char const *, क्योंकि आप इसकी सामग्री को संशोधित नहीं कर सकते हैं (अपरिभाषित व्यवहार के बिना)।

C ++ 11 के रूप में, निहित रूपांतरण को आधिकारिक तौर पर हटा दिया गया था, इसलिए कोड जो उस पर निर्भर करता है (जैसे आपका पहला उदाहरण) अब संकलित नहीं होना चाहिए।

आपने कोड को संकलित करने की अनुमति देने का एक तरीका नोट किया है: हालांकि निहित रूपांतरण हटा दिया गया है, एक स्पष्ट रूपांतरण अभी भी काम करता है, इसलिए आप एक डाली जोड़ सकते हैं। हालाँकि, मैं इस "कोड को ठीक करने" पर विचार नहीं करूंगा ।

सही ढंग से कोड को ठीक करने के लिए पॉइंटर के प्रकार को सही प्रकार में बदलने की आवश्यकता होती है:

char const *p = "abc"; // valid and safe in either C or C++.

जैसा कि इसे C ++ में अनुमति दी गई थी (और अभी भी C में है): केवल इसलिए कि मौजूदा कोड का एक बहुत कुछ है जो उस अंतर्निहित रूपांतरण पर निर्भर करता है, और उस कोड को तोड़ने (कम से कम कुछ आधिकारिक चेतावनी के बिना) जाहिरा तौर पर मानक समितियों को लग रहा था एक बुरा विचार।


8
@rullof: यह काफी खतरनाक है कि यह पोर्टेबिलिटी के बारे में कम से कम कोड (परवाह किए बिना) के लिए कोई सार्थक लचीलापन नहीं देता है। एक स्ट्रिंग शाब्दिक के लिए लेखन आम तौर पर आपके कार्यक्रम को एक आधुनिक ओएस पर निरस्त हो जाएगा, इसलिए कोड को (वहां) लिखने की अनुमति देने से कोई सार्थक लचीलापन नहीं जुड़ता है।
जेरी कॉफिन

3
इस उत्तर में दिया गया कोड स्निपेट char const *p = "abc";" C और C ++ दोनों में वैध और सुरक्षित है ", " C या C ++ दोनों में मान्य और सुरक्षित नहीं है "।
डैनियल ले

4
@ डैनियल उन दोनों वाक्यों का एक ही अर्थ है
केलथ

3
हे भगवान! [गाल में दृढ़ता से जीभ डालें] क्षमा करें, लेकिन "या" यहां सही शब्द है। कोड को C या C ++ के रूप में संकलित किया जा सकता है, लेकिन C और C ++ दोनों के साथ-साथ संकलित नहीं किया जा सकता है। आप या तो चुन सकते हैं, लेकिन आपको एक विकल्प बनाना चाहिए। आप दोनों एक साथ नहीं हो सकते। [सामान्य जीभ का ऑपरेशन फिर से शुरू करें]।
जेरी कॉफिन

2
नहीं, दोनों ही सबसे स्पष्ट और सबसे सही शब्द है। या तो / या सही अर्थ बताने के लिए भी होता है, लेकिन यह तकनीकी रूप से उतना स्पष्ट नहीं है। या अकेला अकाट्य रूप से गलत है ( A या B A और B के बराबर नहीं है )।
Apollys

15

यह ऐतिहासिक कारणों से C में मान्य है। सी ने पारंपरिक रूप से निर्दिष्ट किया कि एक स्ट्रिंग शाब्दिक का प्रकार इसके char *बजाय था const char *, हालांकि उसने यह कहकर योग्य बनाया कि आपको वास्तव में इसे संशोधित करने की अनुमति नहीं है।

जब आप एक कास्ट का उपयोग करते हैं, तो आप अनिवार्य रूप से संकलक को बता रहे हैं कि आप डिफ़ॉल्ट प्रकार के मिलान नियमों से बेहतर जानते हैं, और यह असाइनमेंट को ठीक करता है।


3
यह एक था char[N]और को बदल दिया गया था const char[N]। इसमें आकार की जानकारी संलग्न है।
क्रिस

1
C प्रकार में स्ट्रिंग शाब्दिक है, char[N]लेकिन char*उदाहरण के "abc"लिए नहीं हैchar[4]
Grijesh Chauhan

2

आप स्ट्रैपअप का उपयोग भी कर सकते हैं :

char* p = strdup("abc");
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.