दिलचस्प पोस्ट
एक अस्तित्वपरक प्रकार क्या है? क्या यह व्यवहार में एसएचए टकराव की संभावना को नजरअंदाज करने के लिए सुरक्षित है? लैम्ब्डा द्वारा <सूची से डुप्लिकेट मान निकालने का सबसे तेज़ तरीका <> रेज़र घोषणात्मक दृश्यों से MVC HtmlHelper एक्सटेंशन का उपयोग करना क्या बेहतर है ? कई स्थितियों के साथ अगर कई बयानों, या एक कंसोल पर यह जावास्क्रिप्ट कोड प्रिंट "अपरिभाषित" क्यों करता है? एसक्यूएल: यदि खंड जहां भीतर होता है I आईओएस / ओएसएक्स फ्रेमवर्क्स बनाना: अन्य डेवलपर्स को वितरित करने से पहले उन्हें कॉन्सर्ट करना आवश्यक है? java.rmi.NoSuchObjectException: तालिका में ऐसा कोई ऑब्जेक्ट नहीं है जावा: क्या मतलब है? एंड्रॉइड में फेसबुक पर वीडियो अपलोड करें स्थानीय मैक्सिमा और मिनमा ढूंढना PHP का उपयोग कर MySQL डाटाबेस में आईपी एड्रेस भंडारण टिप्पणियों का उपयोग करते हुए कोड के कुछ भाग के लिए कोड स्वरूपण को अक्षम कैसे करें? वेबड्राइवर 45.05 एमएस के बाद पोर्ट 7055 पर 127.0.0.1 होस्ट करने के लिए कनेक्ट करने में असमर्थ

typedef सूचक const weirdness

कृपया निम्नलिखित कोड पर विचार करें:

typedef struct Person* PersonRef; struct Person { int age; }; const PersonRef person = NULL; void changePerson(PersonRef newPerson) { person = newPerson; } 

किसी कारण के लिए, कंपाइलर केवल-पढ़ने योग्य मान के अनुरूप नहीं है, जो नियतनीय नहीं है। लेकिन कॉन्स्ट कीवर्ड को सूचक कॉन्स्ट नहीं करना चाहिए कोई विचार?

Solutions Collecting From Web of "typedef सूचक const weirdness"

ध्यान दें कि

 typedef int* intptr; const intptr x; 

ऐसा नहीं है:

 const int* x; 

intptr int को सूचक है const intptr int लिए निरंतर सूचक है, निरंतर int लिए सूचक नहीं

इसलिए, एक टाइप किए गए सूचक पॉइंटर के बाद, मैं इसे अब सामग्री के लिए नहीं बना सकता?

कुछ बदसूरत तरीके हैं, जैसे मैक्रोज़ के जीसीसी के प्रकार :

 typedef int* intptr; intptr dummy; const typeof(*dummy) *x; 

लेकिन, जैसा कि आप देख रहे हैं, यदि आप intptr पीछे के प्रकार को जानते हैं तो यह व्यर्थ है

 const PersonRef person = NULL; 

है

 struct Person*const person= NULL; 

तो आप सूचक को परिभाषित कर रहे हैं और वस्तु नहीं

हालांकि समस्या पहले से ऊपर दिए गए उत्तरों से हल हो चुकी है, मुझे इसका कारण याद नहीं है …

तो शायद अंगूठे के नियम के रूप में:

  1. const हमेशा इसके पूर्ववर्ती टोकन को संदर्भित करता है
  2. अगर ऐसी कोई बात नहीं है, तो यह इसके बजाय "टोकन" का उत्तराधिकारी है।

यह नियम वाकई पॉइंटर को कॉन्सेन्ट पॉइंटर्स या कुछ समान रूप से कुछ के लिए घोषित करने में आपकी मदद कर सकता है।

वैसे भी, इसे ध्यान में रखते हुए, यह स्पष्ट होना चाहिए कि क्यों

 struct Person *const person = NULL; 

एक कॉन्स्ट पॉइंटर को एक अस्थायी स्ट्रक्चर घोषित करता है

इसके बारे में सोचें, पॉइंटेटर टोकन * साथ आपके टाइपिंगफेड "समूह" struct Person । तो, लिखने के लिए

 const PersonRef person = NULL; 

आपका कंपाइलर इस तरह कुछ देखता है (छद्म-कोड):

 const [struct Person *]person = NULL; 

चूंकि const के बायीं ओर कुछ भी नहीं है, यह इसे सही struct Person * स्थिर करने के लिए टोकन को हटा देता है

खैर मुझे लगता है, यही कारण है कि मुझे टाइप-फेफ्स द्वारा छद्म संकेतों को छुपाना पसंद नहीं है, जबकि मैं ऐसे टाइपिंगफेप्स की तरह ही करता हूं। लेखन के बारे में क्या

 typedef struct Person { ... } Person; const Person *person; /*< const person */ Person *const pointer; /*< const pointer to mutable person */ 

और यह कंपलर और इंसानों के लिए काफी स्पष्ट होना चाहिए, आप क्या कर रहे हैं

टाइफाइफ़्स के पीछे कभी भी संकेत नहीं छुपें, यह वाकई वास्तव में खराब अभ्यास है और केवल बग पैदा करेगा

ऐसा ही एक कुख्यात बग यह है कि एक टाइपिंगफेड: एड पॉइंटर प्रकार जिसे कॉन्स्ट के रूप में घोषित किया जाता है, को "निरंतर डेटा के लिए निरंतर सूचक" के रूप में माना जाएगा, "निरंतर डेटा के लिए एक निरंतर पॉइंटर" के बजाय जो एक इंटिविट की उम्मीद है । यह आपके कार्यक्रम में क्या होता है।


उपाय:

 typedef struct { int age; } Person; const Person* person = NULL; // non-constant pointer to constant Person 

आप मिल रहे हैं और त्रुटि

 error: assignment of read-only variable 'person' 

बयान पर

 person = newPerson; 

क्योंकि आपने व्यक्ति को const के रूप में घोषित किया है, इसलिए इसका मान केवल पढ़ा जा सकता है …. मान को परिवर्तित नहीं किया जा सकता

अगर आप उस बदलाव को बदलने के लिए जा रहे हैं, तो आप इसे कोंपिंग क्यों कर रहे हैं?

कॉन्स्ट कीवर्ड को हटाने के लिए आपका कोड ठीक काम करेगा