2011-10-25 17 views
7

एक कंपाइलर, सी या सी ++, (उदाहरण के लिए, जीसीसी) const घोषणा का सम्मान कैसे करता है?"कॉन्स्ट" कैसे कार्यान्वित किया जाता है?

उदाहरण के लिए, निम्न कोड में, कैसे संकलक ट्रैक कि चर ciconst है और बदला नहीं जा सकता रहता है?

int 
get_foo() { 
    return 42; 
} 

void 
test() 
{ 
    int i = get_foo(); 
    i += 5; 

    const int ci = get_foo(); 
    // ci += 7; // compile error: assignment of read-only variable ?ci? 
} 
+5

वैसे ही यह var के बारे में सभी संकलन-समय की जानकारी का ट्रैक रखता है iables? –

+0

यह टाइप सिस्टम के माध्यम से संकलित समय पर किया जाता है। –

+1

आपकी टिप्पणी को "केवल पढ़ने योग्य चर के लिए असाइनमेंट" पढ़ना चाहिए। बीटीडब्ल्यू आपको कैसे लगता है कि संकलक इसे एक पूर्णांक जानता है? – hplbsh

उत्तर

9

चर (पता, प्रकार इत्यादि) के लिए प्रतीक जानकारी की किसी अन्य बिट की तरह। आम तौर पर एक प्रतीक तालिका होती है जो घोषित पहचानकर्ताओं के बारे में जानकारी संग्रहीत करती है, और जब भी यह पहचानकर्ता के दूसरे संदर्भ से मुकाबला करता है तो परामर्श दिया जाता है।

(एक और दिलचस्प सवाल यह है कि क्या यह ज्ञान केवल संकलन के दौरान या यहां तक ​​कि रनटाइम के दौरान मौजूद है। अधिकांश भाषाएं संकलन के बाद प्रतीक तालिका को त्यागती हैं, ताकि आप संकलित कोड में हेरफेर कर सकें और पहचानकर्ता घोषित किए जाने पर भी एक नया मूल्य लागू कर सकें 'स्थिरांक'। यह एक परिष्कृत क्रम प्रणाली (और कोड हस्ताक्षर) को रोकने के लिए ले जाता है।)

+0

इसमें जोड़ने के लिए, एक मानक समस्या C++/C कंपाइलर बहुत कुछ नहीं करता है यदि किसी भी चर को चलाने के लिए इस "const" की तरह चर रखने के लिए कुछ भी नहीं है, तो यह केवल उस कोड को उत्पन्न नहीं करता है जो प्रतीक तालिका के माध्यम से इस मान को संशोधित कर सकता है किलियन ने उल्लेख किया। Consequntly, कुछ अन्य संकलक कुछ कोड बना सकते हैं और यदि उस कोड को प्रक्रिया में लोड किया गया था, तो यह उस स्थान पर स्मृति को ओवरराइट कर सकता है। यह बुरी बात है। – Dlongnecker

+1

कॉन्स डेटा को स्मृति के एक अलग ब्लॉक के अंदर रखा जा सकता है और कुछ सिस्टम जो स्मृति के ब्लॉक को वास्तव में केवल पढ़ने के लिए चिह्नित किया जाएगा। कोड की तरह ही एक अलग सेगमेंट में रहता है (शायद कॉन्स डेटा और कोड मिश्रित किया जा सकता है)। बेशक यह केवल स्थिर स्थिरांक और ढेर पर बनाए गए कुछ भी लागू नहीं होता है। –

1

संकलक जानता है कि ciconst है, क्योंकि आप लाइन

const int ci = get_foo(); 

आप अन्य कार्यों के लिए चारों ओर ci पास या अन्य चर के लिए असाइन करें के रूप में के साथ तो यह कहा था, संकलक को बरकरार रखता है कि const- नेस को ऐसा कुछ भी करने से रोककर जो संभावित रूप से अपना मूल्य बदल सकता है।

उदाहरण के लिए, निम्नलिखित एक कंपाइलर त्रुटि उत्पन्न करता है।

int *ci2 = &ci; 
(*ci2)++; 

क्योंकि संकलक आपको सीआई के मूल्य को संशोधित नहीं करने देगा।

+0

आपके बाद के उदाहरण को वृद्धि ऑपरेशन के बावजूद एक कंपाइलर त्रुटि उत्पन्न करनी चाहिए। कोई पॉइंटर-टू-कॉन्स वैल्यू को पॉइंटर-टू-गैर-कॉन्स वैरिएबल को असाइन नहीं कर सकता है। – Novelocrat

3
बेशक

यह प्रत्येक संकलक के कार्यान्वयन ऊपर है, लेकिन संक्षेप में, यह चर के const और volatile क्वालिफायर (यदि हो तो) अपनी चर प्रतीक तालिका में अन्य जानकारी के साथ-साथ इस तरह के चर के प्रकार के रूप में और चाहे या नहीं संग्रहीत करता है यह एक सूचक/संदर्भ है।

+0

"सीवी क्वालीफायर"? निश्चित रूप से चर के पाठ्यक्रम पाठ्यक्रम नहीं है! – Gabe

+1

@Gabe: मानक धारा 3.9.3 "सीवी क्वालीफायर्स" में उनके बारे में बहुत कुछ (कॉन्स/अस्थिर) बोलता है। –

1

मुझे यकीन है कि अन्य अधिक विस्तृत कर सकते हैं, लेकिन संक्षेप में, हाँ। कंपाइलर सभी प्रकार के विनिर्देशकों का ट्रैक रखता है ताकि यह जान सके कि सीआई "कॉन्स इंट" प्रकार है, और "int" नहीं है।

1

के रूप में अन्य लोगों ने कहा, const उसी तरह संकलक तथ्य यह है कि एक चर एक int है पटरियों संकलक द्वारा पता लगाया जाता है। असल में, मैंने पढ़ा है कि कम से कम gcc const intint से एक अलग प्रकार पर विचार करता है, इसलिए इसे संशोधक के रूप में भी ट्रैक नहीं किया जाता है, यह int जैसा सटीक रूप से ट्रैक किया जाता है।

ध्यान दें कि आप वास्तव में सूचक कास्टिंग के माध्यम से एक const का मूल्य बदल सकते हैं, लेकिन परिणाम अपरिभाषित है:

#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 
     const int c = 0; 
     printf("%d\n", c); 
     ++*(int*)&c; 
     printf("%d\n", c); 
} 

मेरी मशीन जीसीसी का उपयोग करते हुए, इस

0 
1 

लेकिन साथ संकलन प्रिंट जी ++

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