2011-08-10 17 views
16

से लागू रूपांतरण क्यों मेरा कंपाइलर (जीसीसी) char** से const char** पर निहित रूप से क्यों नहीं डाला गया है?char ** से const char **

Thie निम्नलिखित कोड:

oi.cpp: In function ‘int main(int, char**)’: 
oi.cpp:8:12: error: invalid conversion from ‘char**’ to ‘const char**’ [-fpermissive] 
oi.cpp:3:6: error: initializing argument 1 of ‘void print(const char**)’ [-fpermissive] 
+7

[मुझे 'Foo **' → 'Foo const **' ?? (http://www.parashift.com/c++-faq-lite/const-correctness.html#faq को परिवर्तित करने में त्रुटि क्यों मिल रही है -18.17) – fredoverflow

+0

"अंतर्निहित कास्ट" जैसी कोई चीज़ नहीं है। एक 'कास्ट' एक स्पष्ट ऑपरेटर है जो रूपांतरण निर्दिष्ट करता है। निहित रूपांतरण भी हो सकते हैं। ("कास्ट" ऑपरेटर है, "रूपांतरण" ऑपरेशन है।) –

+0

@ केथ: मुझे लगता है कि शब्दावली कोई समस्या नहीं है। आखिरकार, हम "अप-कास्ट" कहते हैं और "अप-रूपांतरण" नहीं करते हैं। या, कम से कम, मैं यह कहता हूं। :-) –

उत्तर

16

इस तरह के एक रूपांतरण आप char* के अपने सरणी, जो असुरक्षित हो जाएगा में एक const char* डाल करने की अनुमति होगी:

#include <iostream> 

void print(const char** thing) { 
    std::cout << thing[0] << std::endl; 
} 

int main(int argc, char** argv) { 
    print(argv); 
} 

निम्न त्रुटि देता है। print में आप कर सकता है:

thing[0] = "abc"; 

अब argv[0], एक स्ट्रिंग शाब्दिक कि बदला नहीं जा सकता को इंगित करेंगे, जबकि main उम्मीद यह गैर स्थिरांक (char*) किया जाना है। तो टाइप सुरक्षा के लिए इस रूपांतरण की अनुमति नहीं है।

+0

बहुत अच्छी व्याख्या मैंने इस तरह से नहीं सोचा, धन्यवाद। इसे 'char * const * thing' में बदलकर अपेक्षित काम करता है। हालांकि फिर भी 'कॉन्स चार * कॉन्स * चीज' काम करना चाहिए, लेकिन नहीं। मैं उस पर और जानकारी के लिए बहुत अच्छा होगा। – nert

+0

तो यह सी ++ के लिए काम करता है लेकिन सी के लिए नहीं है, इसलिए मैंने इसके लिए नया प्रश्न पोस्ट किया क्योंकि मुझे कोई जवाब नहीं मिल रहा है: https://stackoverflow.com/questions/35319842/why-c-doesnt-allow-implicit -conversion-from-char-to-const-char-const-और – nert

2

क्योंकि यह हमें निरंतर मूल्य को संशोधित करने की अनुमति दे सकता है। यह समझने के लिए यहां पढ़ें: http://c-faq.com/ansi/constmismatch.html

6

@Fred ओवरफ़्लो का link to the FAQ एक पूर्ण उत्तर है। लेकिन (माफ करना मार्शल) यह सबसे स्पष्ट स्पष्टीकरण नहीं है। मुझे नहीं पता कि मेरा और स्पष्ट है, लेकिन मुझे उम्मीद है।


बात, अगर p एक char* सूचक है तो यह जो भी हो पर इंगित है संशोधित लिए इस्तेमाल किया जा सकता है।

और तुम एक सूचक pp कि p के लिए अंक प्राप्त कर सकते हैं, लेकिन प्रकार char const** की pp साथ है, तो आप pp इस्तेमाल कर सकते हैं p करने के लिए एक const char का पता असाइन करने के है।

और उसके साथ, आप को संशोधित करने के लिए p का उपयोग कर सकते हैं। या, आपको लगता है कि आप कर सकते हैं। लेकिन const char केवल पढ़ने-योग्य स्मृति और नरक में भी हो सकता है;

कोड में:

char const  c = 'a'; 
char*    p = 0; 
char const**  pp = &p;    // Not allowed. :-) 

*pp = &c;  // p now points to c. 
*p = 'b';  // Uh oh. 


अपने कोड के लिए एक व्यावहारिक समाधान है कि संकलन नहीं है, है & hellip के रूप में;

#include <iostream> 

void print(const char** thing) { 
    std::cout << thing[0] << std::endl; 
} 

int main(int argc, char** argv) { 
    print(argv); // Dang, doesn't compile! 
} 

बस करें और नरक;

#include <iostream> 

void print(char const* const* thing) 
{ 
    std::cout << thing[0] << std::endl; 
} 

int main(int argc, char** argv) 
{ 
    print(argv); // OK. :-) 
} 

चीयर्स & hth।,

+0

चूंकि यह थ्रेड सी और सी ++ दोनों पोस्टों से डुप्लिकेट के रूप में जुड़ा हुआ है: ध्यान दें कि अंतिम चाल सी में काम नहीं करती है (इसके लिए कोई अच्छा कारण नहीं है सी में काम नहीं करते, यह शायद मानक समिति द्वारा सिर्फ एक निरीक्षण है)। –

+0

@MattMcNabb बस * जोड़ा * सी टैग। जब मैंने इसे लिखा था तो यह जवाब ठीक और पूरा था। यह सी के लिए काम नहीं करता है, यह पास्कल के लिए काम नहीं करता है, यह हास्केल के लिए काम नहीं करता है, या किसी अन्य भाषा के लिए टैग जोड़ता है। –

3

ध्यान दें, कि हालांकि

void dosmth(const char** thing); 

int main(int argc, char** argv) { 
    dosmth(argv); 

मना किया है, तो आप और

void dosmth(const char* const* thing); 

int main(int argc, char** argv) { 
    dosmth(argv); 

करना चाहिए कर सकते हैं कौन सा संभव है कि आप वैसे भी चाहता था।यहां बिंदु यह है कि thing अब const char* सरणी को संदर्भित करता है जो स्वयं ही अपरिवर्तनीय है और संदर्भित मान char स्वयं अपरिवर्तनीय हैं। तो, "पर इसे देखने के लिए, लेकिन इसे" बदलें, परिदृश्य, const char* const* उपयोग करने के लिए प्रकार है।

नोट: मैंने जितना संभव हो सके const संशोधक लिखने की कोशिश करने के अधिक सामान्य (लेकिन मेरी राय में निम्न) मानक का उपयोग किया। व्यक्तिगत रूप से, मैं के बजाय char const* const* लिखने की सलाह देता हूं क्योंकि यह इस तरह से अधिक संक्षेप में है।

+0

मैंने यह भी सोचा कि यह भी काम करना चाहिए, लेकिन जीसीसी चाहता है कि पहला न होना वहां न हो। विशेष रूप से: 'कॉन्स char * const * thing' एक त्रुटि उत्पन्न करता है, लेकिन 'char * const * thing' नहीं करता है। – nert

+0

तो यह सी ++ के लिए काम करता है लेकिन सी के लिए नहीं है, इसलिए मैंने इसके लिए नया प्रश्न पोस्ट किया क्योंकि मुझे कोई जवाब नहीं मिल रहा है: https://stackoverflow.com/questions/35319842/why-c-doesnt-allow-implicit रूपांतरण-से-चार-टू-स्थिरांक-चार-स्थिरांक-और – nert

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