दिलचस्प पोस्ट
जहां LINQ में खंड में WPF डाटाबेसिंग: मैं "मूल" डेटा संदर्भ का उपयोग कैसे करूं? codeigniter वेबसाइट बहु भाषा बनाने का सबसे अच्छा तरीका लैंग एरेज़ से फोन करना लैंग सत्र पर निर्भर करता है? स्टैक वैरिएबल जीसीसी __डेटाइट __ (गठबंधन (एक्स)) द्वारा गठबंधन कर रहे हैं? मेरी समानता = (एक एकल बराबर) का उपयोग सही ढंग से काम क्यों नहीं करता? जावास्क्रिप्ट इंजन को एनआईटी में एम्बेड करना जावास्क्रिप्ट में नए जोड़े गए तत्व के लिए onclick घटना जोड़ें फायरबग (या इसी तरह के टूल) के साथ जावास्क्रिप्ट / jQuery इवेंट बाइंडिंग डिबग कैसे करें मार्शमॉलो में संग्रहण अनुमति त्रुटि वसंत – @ लेनदेन – पृष्ठभूमि में क्या होता है? स्नैपशॉट दृश्य और गतिशील दृश्य के बीच क्या अंतर है? सी: बहु-थ्रेडेड प्रोग्राम में समय मापने के लिए घड़ी () का उपयोग करना स्थान पर बिटमैप सहेजें हेक्स आरजीबी रंग कोड को यूआईकोलोर में कनवर्ट कैसे करें? उपयोगकर्ता 'रूट @ लोकलहोस्ट' के लिए प्रवेश निषेध (पासवर्ड का उपयोग करते हुए: नहीं)

सी में 'const char * const *' के लिए मैं 'char **' को क्यों नहीं परिवर्तित कर सकता हूं?

निम्न कोड स्निपेट (सही ढंग से) सी में एक चेतावनी और सी + + में एक त्रुटि देता है (जीसीसी और जी ++ का प्रयोग करके, संस्करण 3.4.5 और 4.2.1 संस्करण के साथ परीक्षण किया गया है; एमएसवीसी पर ध्यान नहीं लगता है):

char **a; const char** b = a; 

मैं इसे समझ सकता हूं और स्वीकार कर सकता हूं।
इस समस्या का सी ++ समाधान बी को कॉन्स्ट char * कॉन्स्ट * के रूप में बदलने के लिए है, जो पॉइंटर्स के पुन: असाइन की अनुमति नहीं देता है और आपको कॉन्स्ट-अचुरता ( सी ++ एफएक्यू ) को बाधित करने से रोकता है।

 char **a; const char* const* b = a; 

हालांकि, शुद्ध सी में, सही संस्करण (const char * const * का उपयोग करते हुए) अभी भी एक चेतावनी देता है, और मुझे समझ में नहीं आ रहा है कि क्या कलाकारों का उपयोग किए बिना इस पर चारों ओर निकलने का कोई तरीका है?

स्पष्टीकरण देना:
1) यह सी में एक चेतावनी क्यों उत्पन्न करता है? यह पूरी तरह से सुरक्षित होना चाहिए, और C ++ कंपाइलर इसे पहचानने लगता है जैसे कि।
2) कहां (और संकलक लागू होने के दौरान) इस पैरामीटर के रूप में स्वीकार करने के बारे में जाने का सही तरीका क्या है कि मैं उन पात्रों को संशोधित नहीं करूँगा जो यह इंगित करता है? उदाहरण के लिए, यदि मैं फ़ंक्शन लिखना चाहता हूं:

 void f(const char* const* in) { // Only reads the data from in, does not write to it } 

और मैं इसे चारों ओर खड़ा करना चाहता था **, पैरामीटर के लिए सही प्रकार क्या होगा?

संपादित करें: जिन लोगों ने प्रतिक्रिया दी है, उनके लिए धन्यवाद, खासकर उन लोगों ने जो प्रश्न को संबोधित किया और / या मेरी प्रतिक्रियाओं का पालन किया।

मैंने जवाब स्वीकार कर लिया है कि मैं क्या करना चाहता हूं, बिना किसी कलाकार के किया जा सकता, भले ही यह संभव नहीं है या नहीं।

वेब के समाधान से एकत्रित समाधान "सी में 'const char * const *' के लिए मैं 'char **' को क्यों नहीं परिवर्तित कर सकता हूं?"

कुछ साल पहले मुझे यह समस्या थी और यह मुझे अंत तक बर्बाद नहीं किया।

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

अंत में, सी मानक में यह सिर्फ एक समस्या है। मुझे उम्मीद है कि अगले मानक (या तकनीकी रिपोर्ट) इस पते पर संबोधित करेंगे

> हालांकि, शुद्ध सी में, यह अभी भी एक चेतावनी देता है, और मुझे समझ में नहीं आता क्यों

आपने पहले से ही समस्या की पहचान की है – यह कोड कंस्ट्र-सही नहीं है "कॉस्ट सही" का अर्थ है कि, const_cast और c-style को छोड़कर const को हटाने के अलावा, आप कभी भी const const पॉइंट या संदर्भ के माध्यम से एक const वस्तु को संशोधित नहीं कर सकते।

Const-correctness का मान – const, बड़े भाग में, प्रोग्रामर त्रुटियों का पता लगाने के लिए है यदि आप const के रूप में कुछ घोषित करते हैं, तो आप बता रहे हैं कि आपको नहीं लगता है कि इसे संशोधित किया जाना चाहिए – या कम से कम, केवल उन const संस्करण तक पहुंच के साथ ही इसे संशोधित करने में सक्षम नहीं होना चाहिए। विचार करें:

 void foo(const int*); 

घोषित होने पर, फू को इसके तर्क से इंगित पूर्णांक को संशोधित करने की अनुमति नहीं है

यदि आप सुनिश्चित नहीं हैं कि आपने जो कोड पोस्ट किया है, वह सही नहीं है, तो निम्न कोड पर विचार करें, केवल हैप्पीड्यूड्स के कोड से थोड़ा अलग है:

 char *y; char **a = &y; // a points to y const char **b = a; // now b also points to y // const protection has been violated, because: const char x = 42; // x must never be modified *b = &x; // the type of *b is const char *, so set it // with &x which is const char* .. // .. so y is set to &x... oops; *y = 43; // y == &x... so attempting to modify const // variable. oops! undefined behavior! cout << x << endl; 

गैर-कॉन्स्ट प्रकार केवल विशिष्ट प्रकारों में कॉन्स्ट प्रकार में कनवर्ट कर सकते हैं, जो किसी विशेष प्रकार के बिना डेटा प्रकार पर 'const' की किसी भी तरह की रोकथाम को रोकने के लिए है।

ऑब्जेक्ट्स की शुरूआत में घोषित कंस विशेष रूप से विशेष हैं – संकलक यह मान सकते हैं कि वे कभी भी बदल नहीं सकते हैं। हालांकि, अगर 'बी' को किसी कलाकार के बिना 'ए' का मान सौंपा जा सकता है, तो आप अनजाने में एक कॉन्स्ट वेरिएबल को संशोधित करने का प्रयास कर सकते हैं। यह न केवल उस जांच को तोड़ता है जिसे आपने कंपाइलर से कहा था, आपको वैरिएबल वैल्यू बदलने से इनकार करने की अनुमति नहीं दी जाएगी – यह आपको कंपाइलर ऑप्टिमाइजेशन को तोड़ने की भी अनुमति देगा!

कुछ कंपाइलर पर, यह '42' प्रिंट करेगा, कुछ '43' पर, और अन्य, प्रोग्राम क्रैश होगा।

संपादित करें: जोड़ें:

हैप्पीड्यूड: आपकी टिप्पणी जगह पर है या तो सी भाषा, या सी संकलक जो आप उपयोग कर रहे हैं, C *+ भाषा से भिन्न रूप से अलग-अलग तरह का मान लेता है; शायद केवल इस स्रोत रेखा के लिए कंपाइलर चेतावनी को चुप्पी पर विचार करना

संपादन-हटाएं: हटाए गए टाइपो

संगत माना जा करने के लिए, स्रोत पॉइंटर को तुरंत पूर्वकाल इंडिरेक्शन स्तर में होना चाहिए। इसलिए, यह आपको जीसीसी में चेतावनी देगा:

 char **a; const char* const* b = a; 

लेकिन यह नहीं होगा:

 const char **a; const char* const* b = a; 

वैकल्पिक रूप से, आप इसे डाल सकते हैं:

 char **a; const char* const* b = (const char **)a; 

जैसा कि आपने उल्लेख किया है, फ़ंक्शन एफ () को खोलने के लिए आपको एक ही कलाकार की आवश्यकता होगी जहां तक ​​मुझे पता है, इस मामले में (सी ++ को छोड़कर) कोई असंतुलित रूपांतरण करने का कोई रास्ता नहीं है।

यह गुस्सा आ रहा है, लेकिन यदि आप एक दूसरे स्तर के पुनर्निर्देशन को तैयार करने के लिए तैयार हैं, तो आप पॉइंट-टू-पॉइंटर में नीचे जाने के लिए अक्सर निम्न कर सकते हैं:

 char c = 'c'; char *p = &c; char **a = &p; const char *bi = *a; const char * const * b = &bi; 

इसका थोड़ा अलग अर्थ है, लेकिन यह आम तौर पर काम करता है, और यह एक कलाकार का उपयोग नहीं करता है।

मैं कम से कम एमएसवीसी 14 (वीएस 2के 5) और जी ++ 3.3.3 पर कॉन्स्ट चार * कंस्ट्रक्ट * का इस्तेमाल करते समय त्रुटि प्राप्त नहीं कर पा रहा हूं। जीसीसी 3.3.3 एक चेतावनी जारी करता है, जो मुझे बिल्कुल यकीन नहीं है कि क्या यह सही है।

test.c:

 #include <stdlib.h> #include <stdio.h> void foo(const char * const * bar) { printf("bar %s null\n", bar ? "is not" : "is"); } int main(int argc, char **argv) { char **x = NULL; const char* const*y = x; foo(x); foo(y); return 0; } 

सी कोड के रूप में संकलन के साथ आउटपुट: cl / TC / W4 / Wp64 test.c

 test.c(8) : warning C4100: 'argv' : unreferenced formal parameter test.c(8) : warning C4100: 'argc' : unreferenced formal parameter 

सी ++ कोड के रूप में संकलन के साथ आउटपुट: cl / TP / W4 / Wp64 test.c

 test.c(8) : warning C4100: 'argv' : unreferenced formal parameter test.c(8) : warning C4100: 'argc' : unreferenced formal parameter 

जीसीसी के साथ उत्पादन: जीसीसी-वाल test.c

 test2.c: In function `main': test2.c:11: warning: initialization from incompatible pointer type test2.c:12: warning: passing arg 1 of `foo' from incompatible pointer type 

जी ++ के साथ आउटपुट: जी ++ -Wall test.C

उत्पादन नही

मुझे पूरा यकीन है कि कॉन्स्ट कीवर्ड यह नहीं दर्शाता कि डेटा को बदला नहीं जा सकता है / स्थिर है, केवल यह कि डेटा को केवल-पढ़ने के लिए माना जाएगा इस पर विचार करो:

 const volatile int *const serial_port = SERIAL_PORT; 

जो मान्य कोड है कैसे अस्थिर और संयोजित कर सकते हैं अस्तित्व? सरल। अस्थिरता संकलक को हमेशा बताता है कि डेटा का उपयोग करते समय मेमोरी को पढ़ने के लिए और कंट्रोलर को सीरियल_पोर्ट पॉइंटर का उपयोग करके स्मृति में लिखने के लिए एक त्रुटि बनाने के लिए कहता है।

क्या कंपाइलर के अनुकूलक की मदद करता है? नहीं बिलकुल नहीं। कंटैस्टेशन को कास्टिंग के जरिए डेटा से जोड़ा और हटाया जा सकता है, इसलिए कंपाइलर यह समझ नहीं सकता है कि कॉन्स्ट डेटा वास्तव में स्थिर है (चूंकि कास्ट एक अलग अनुवाद इकाई में किया जा सकता है)। सी ++ में आपके पास मामले को जटिल करने के लिए अयोग्य शब्द भी है।

 char *const p = (char *) 0xb000; //error: p = (char *) 0xc000; char **q = (char **)&p; *q = (char *)0xc000; // p is now 0xc000 

क्या होता है, जब मेमोरी को लिखने के लिए एक प्रयास किया जाता है, वास्तव में केवल पढ़ने के लिए (रोम, उदाहरण के लिए) शायद मानक में बिल्कुल भी परिभाषित नहीं होता है