2011-12-14 14 views
16

कृपया नीचे दिए गए कोड पर विचार करें:typedef सूचक स्थिरांक weirdness

typedef struct Person* PersonRef; 
struct Person { 
    int age; 
}; 

const PersonRef person = NULL; 

void changePerson(PersonRef newPerson) { 
    person = newPerson; 
} 

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

+2

"लेकिन स्थिरांक कीवर्ड सूचक स्थिरांक नहीं करना चाहिए।" है ना? संक्षिप्त उत्तर: टाइपपीफ का उपयोग न करें, वे केवल आपको भ्रमित करने के लिए हैं। उन्हें याद रखें जब तक आपको उनकी आवश्यकता न हो। – wildplasser

+12

@ विल्डप्लेसर: "टाइपपीफ का उपयोग न करें" अच्छी सलाह नहीं है। शायद "टाइपिफ के पीछे पॉइंटर्स छुपाएं" अधिक उपयुक्त है ... –

+1

मैं अलग होना चाहता हूं। यह * एक अच्छी सलाह है। एक टाइपपीफ के पीछे छिपाने वाले structs सिर्फ छिपाने वाले पॉइंटर्स के रूप में उलझन में है। यह केवल आपके मानसिक नामस्थान को प्रदूषित करने में कार्य करता है। सिंटैक्स हाइलाइटिंग के बिना भी मैंने "स्ट्रक्चर व्यक्ति * पी" को आसान और तेज़ "पीपीर्सन पी" पढ़ा। – wildplasser

उत्तर

33

ध्यान दें कि

typedef int* intptr; 
const intptr x; 

के समान नहीं है:

const int* x; 

intptr int करने के लिए सूचक है। const intptrint पर निरंतर सूचक है, स्थिर int पर सूचक नहीं है।

तो, टाइपिफ़ पॉइंटर के बाद, मैं इसे अब सामग्री में नहीं बना सकता?

ऐसे जीसीसी के typeof macro के रूप में कुछ बदसूरत तरीके हैं:

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

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

+0

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

5
const PersonRef person = NULL; 

struct Person*const person= NULL; 

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

+0

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

+1

हां, बिल्कुल, कारणों में से एक कारण पॉइंटर्स का 'टाइपपीफ' आमतौर पर एक बुरा विचार है। –

0

आप हो रही है और त्रुटि

error: assignment of read-only variable ‘person’ 

बयान

person = newPerson; 

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

यदि आप उस भयानक को बदलने जा रहे हैं तो आप इसे क्यों बना रहे हैं?

निकालें स्थिरांक कीवर्ड अपने कोड इच्छा ठीक काम करता है

+0

हां, निश्चित रूप से, मुझे आश्चर्य है कि पॉइंटर इस्ट कॉन्स्ट क्यों है और वह सामग्री नहीं जहां यह इंगित करता है।यही वह है जो मुझे उम्मीद थी ... – Johannes

1

कभी typedefs पीछे संकेत छुपाने के लिए, यह वास्तव में बहुत बुरी बात है और केवल कीड़े पैदा करेगा। एड सूचक प्रकार है कि स्थिरांक के रूप में घोषित किया जाता है एक "गैर-निरंतर डेटा के लिए निरंतर सूचक" के रूप में माना जाएगा, के बजाय "एक गैर निरंतर निरंतर आंकड़ों के सूचक" है जो: इस तरह के

एक कुख्यात बग है कि एक typedef है क्या एक सहजता से उम्मीद करता है। यह आपके कार्यक्रम में क्या होता है।


समाधान: समस्या पहले से ही ऊपर जवाब द्वारा हल किया जाता है

typedef struct 
{ 
    int age; 
} Person; 

const Person* person = NULL; // non-constant pointer to constant Person 
3

करते हुए मैं कारण है कि याद आती है कर ...

तो शायद एक सामान्य नियम के रूप में:

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

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

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

struct Person *const person = NULL; 

एक परिवर्तनशील struct करने के लिए एक स्थिरांक सूचक की घोषणा की।

, इसके बारे में सोचो अपने typedef "समूह" सूचक टोकन * साथ struct Person

const [struct Person *]person = NULL; 

const के लिए कुछ भी नहीं बचा है, यह टोकन deklares यह सही struct Person * निरंतर है करने के लिए: तो,

const PersonRef person = NULL; 

अपने संकलक लिखने के लिए इस (छद्म कोड) की तरह कुछ देखता है।

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

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

और यह संकलक और मनुष्यों के लिए बिल्कुल स्पष्ट होना चाहिए, आप क्या कर रहे हैं।