C99 मानक 6.5.16: 2 में कहता है:
एक असाइनमेंट ऑपरेटर के पास अपने बाएं ऑपरेंड के रूप में एक परिवर्तनीय अंतराल होगा।
और 6.3.2.1:1 में:
एक परिवर्तनीय अंतराल एक अंतराल है जिसमें सरणी प्रकार नहीं होता है, एक अपूर्ण प्रकार नहीं होता है, एक कॉन्स्टेबल-योग्य प्रकार नहीं होता है, और यदि यह एक संरचना या संघ है, जिसमें कोई सदस्य नहीं है (सहित, पुनरावर्ती, कोई सदस्य) या सभी निहित समुच्चय या संघ) का तत्व एक कास्ट-योग्य प्रकार के साथ।
अब, चलो const
struct
एक const
क्षेत्र के साथ एक गैर पर विचार करें ।
typedef struct S_s {
const int _a;
} S_t;
मानक के अनुसार, निम्न कोड अपरिभाषित व्यवहार (UB) है:
S_t s1;
S_t s2 = { ._a = 2 };
s1 = s2;
इसके साथ शब्दार्थ समस्या यह है कि संलग्न इकाई ( struct
) को लिखने योग्य (गैर-केवल पढ़ने योग्य) माना जाना चाहिए, इकाई के घोषित प्रकार ( S_t s1
) से देखते हुए , लेकिन मानक के शब्द (2 कारणों) द्वारा लिखने योग्य नहीं माना जाना चाहिए शीर्ष पर) const
क्षेत्र के कारण _a
। मानक एक प्रोग्रामर को कोड पढ़ने के लिए यह स्पष्ट नहीं करता है कि असाइनमेंट वास्तव में एक यूबी है, क्योंकि यह बताना असंभव है कि डब्ल्यू / ओ struct S_s ... S_t
प्रकार की परिभाषा ।
इसके अलावा, क्षेत्र में केवल पढ़ने के लिए उपयोग केवल कृत्रिम रूप से लागू किया जाता है। वहाँ कोई रास्ता नहीं const
गैर के कुछ क्षेत्रों const
struct
वास्तव में केवल पढ़ने के लिए भंडारण के लिए रखा जा रहा है। लेकिन मानक के ऐसे शब्दों के कारण उस कोड को बदल दिया जाता है, जो const
इन क्षेत्रों के एक्सेसर प्रक्रियाओं में जानबूझकर खेतों के क्वालीफायर को दूर कर देता है , जैसे कि ( क्या यह C में संरचना के क्षेत्रों को कांस्टेबल बनाने के लिए एक अच्छा विचार है? ):
(*)
#include <stdlib.h>
#include <stdio.h>
typedef struct S_s {
const int _a;
} S_t;
S_t *
create_S(void) {
return calloc(sizeof(S_t), 1);
}
void
destroy_S(S_t *s) {
free(s);
}
const int
get_S_a(const S_t *s) {
return s->_a;
}
void
set_S_a(S_t *s, const int a) {
int *a_p = (int *)&s->_a;
*a_p = a;
}
int
main(void) {
S_t s1;
// s1._a = 5; // Error
set_S_a(&s1, 5); // OK
S_t *s2 = create_S();
// s2->_a = 8; // Error
set_S_a(s2, 8); // OK
printf("s1.a == %d\n", get_S_a(&s1));
printf("s2->a == %d\n", get_S_a(s2));
destroy_S(s2);
}
तो, किसी कारण से, एक पूरे के struct
लिए केवल-पढ़ने के लिए यह घोषित करने के लिए पर्याप्त हैconst
const S_t s3;
लेकिन पूरी तरह struct
से गैर-पढ़ने के लिए-केवल इसे w / o घोषित करने के लिए पर्याप्त नहीं है const
।
मुझे लगता है कि बेहतर होगा, या तो है:
- खेतों के
const
साथ गैर- संरचनाओं के निर्माण को बाधित करने के लिएconst
, और इस तरह के एक मामले में नैदानिक जारी करना। इससे यह स्पष्ट हो जाएगा किstruct
केवल पढ़ने के लिए फ़ील्ड केवल-पढ़ने के लिए है। const
गैर-const
संरचना से संबंधित क्षेत्र को लिखने के मामले में व्यवहार को परिभाषित करने के लिए मानक के अनुरूप कोड (*) से ऊपर बनाने के लिए।
अन्यथा व्यवहार संगत और समझने में कठिन नहीं है।
तो, सी स्टैंडर्ड के लिए कारण क्या है- const
पुनरावर्ती रूप से, जैसा कि यह कहता है?