2010-05-28 18 views
9

क्या अलग-अलग क्षेत्रों के साथ एक सी फ़ाइल में एक ही नाम के एकाधिक स्थिर चर घोषित करना संभव है? मैंने इसे जांचने के लिए एक सरल कार्यक्रम लिखा और जीसीसी में इसे संकलित और ठीक काम किया।क्या एक ही सी फ़ाइल में एक ही नाम के साथ एकाधिक स्थैतिक चर घोषित करना संभव है?

कोड:

static int sVar = 44; 

void myPrint2() 
{ 
    printf("sVar = %d\n", sVar++); 
} 

void myPrint() 
{ 
    static int sVar =88; 
    printf("sVar = %d\n", sVar++); 
} 

int main(void) 
{ 
    static int sVar = 55; 
    int i = 0; 
    for (i = 0; i < 5; i++) 
     myPrint();  
    printf("sVar = %d\n", sVar); 
    myPrint2(); 
    return(0); 
} 

अब मेरे सवाल है के बाद से सभी "स्थिर" चर एक ही अनुभाग (.data) में निवास करेंगे तो हम एक खंड में एक ही नाम के साथ कई चर हो सकता है कैसे?

मैं अलग अनुभाग की जांच करने के लिए objdump का इस्तेमाल किया और पाया कि सभी स्थैतिक चर (sVar) .data खंड में लेकिन विभिन्न नामों वाली इस प्रकार थे:

0804960c l  O .data 00000004    sVar 
08049610 l  O .data 00000004    sVar.1785 
08049614 l  O .data 00000004    sVar.1792 

क्यों कम्पाइलर वेरिएबल के नाम बदल रहा है है (चूंकि सी नाम उलझन का समर्थन नहीं करता है)?

+0

वे केवल अस्थायी, आंतरिक नाम हैं। सी ++ में नाम उलझन डीएलएल निर्यात जैसी चीजों पर लागू होता है। यह एक अलग बात है। – Puppy

+2

सी नाम उलझन की अनुमति देता है, और आपने इसे अभी दिखाया है। – MSalters

+0

नाम मैंगलिंग एक कार्यान्वयन विस्तार है। सी इस तरह "अनुमति" नहीं देता है, यह एक सुविधा को लागू करने के लिए इसका उपयोग करता है (जाहिर है - मुझे नहीं पता था कि आप यह कर सकते हैं, लेकिन आप हर दिन कुछ नया सीखते हैं)। इसी प्रकार सी ++ नाम मैंगलिंग को "अनुमति" नहीं देता है, यह फ़ंक्शन ओवरलोडिंग को लागू करने के लिए इसका उपयोग करता है। – JeremyP

उत्तर

17

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

+0

यह सच है लेकिन स्थानीय और वैश्विक स्थैतिक चर दोनों एक ही डेटा अनुभाग में रह रहे हैं और चूंकि आपके पास समान डेटा अनुभागों में समान नाम के एकाधिक चर नहीं हो सकते हैं इसलिए मेरा मानना ​​है कि संकलक नाम बदल रहा है। अगर मैं गलत हूं कृपया मुझे सही। धन्यवाद –

+2

@ मोहम्मद: जिस तरह से मैं आपको समझता हूं, आपने अभी मेरी दूसरी वाक्य दोहराई है। मुझे इसके साथ असहमत क्यों होना चाहिए? ':)' – sbi

+0

हां सच .. :) क्या इसका मतलब है सी संकलन नाम mangling का भी समर्थन करते हैं ?? –

2

आपका पहला sVar दायर करने के लिए वैश्विक है, दूसरा एक समारोह myPrint() लिए स्थानीय है और तीसरे एक स्थिर main()

समारोह स्तर चर के लिए स्थानीय समारोह के बाहर सुलभ नहीं हैं - वे बस आगामी कॉल पर उनके मूल्यों को बनाए रखने । मुझे लगता है कि जब आप अपना कोड चलाते हैं तो आपने पहले ही यह ध्यान दिया है।

1

स्थैतिक कीवर्ड का अर्थ अलग-अलग अर्थ है जब यह वैश्विक और स्थानीय है, पहले sVar अन्य वैश्विक इकाइयों के लिए एक वैश्विक चर उपलब्ध है। और स्थिर चर sVarmyPrint() और main() विभिन्न क्षेत्रों में हैं, इसलिए वे अलग-अलग चर हैं। myPrint()sVar के शरीर में स्थानीय स्थैतिक (sVar छिपाते हुए) को संदर्भित करता है, myPrint2() में यह वैश्विक (यह किसी भी स्थानीय द्वारा छिपा हुआ नहीं है), और main() में संदर्भित करता है, यह स्थानीय static sVar को संदर्भित करता है, जो फिर से वैश्विक को छुपाता है पल इसे घोषित किया गया था।

6

दृश्यता और सीमा के बीच एक अंतर है; भी, static कीवर्ड के दायरे के आधार पर अलग-अलग अर्थ हैं।

sVar (myPrint :: उत्तर और मुख्य :: उत्तर) के ब्लॉक गुंजाइश संस्करण के लिए static कीवर्ड को जोड़ने का बदलता है उनके हद (जीवन), लेकिन उनकी दृश्यता; दोनों केवल अपने संबंधित कार्यों में दिखाई दे रहे हैं, और फ़ाइल स्कोप संस्करण को उनके स्थानीय दायरे में छाया या छुपाएंगे।यह इंगित करता है कि चर के पास स्थिर सीमा है, जिसका अर्थ है कि उनके लिए स्मृति कार्यक्रम शुरू होने तक और कार्यक्रम तक समाप्त होने तक आयोजित किया जाता है (स्वचालित या स्थानीय सीमा के विपरीत, जहां उनका जीवनकाल उस क्षेत्र तक सीमित है जिसमें उन्हें परिभाषित किया गया है)।

staticsVar के फ़ाइल स्कोप संस्करण में कीवर्ड जोड़ने से इसकी सीमा (फ़ाइल स्कोप चर के परिभाषा के अनुसार स्थिर सीमा नहीं है) बदलती है, लेकिन यह अन्य अनुवाद इकाइयों के संबंध में इसकी दृश्यता बदलती है; नाम लिंकर को निर्यात नहीं किया गया है, इसलिए इसे किसी अन्य अनुवाद इकाई से नाम से नहीं पहुंचा जा सकता है। यह अभी भी वर्तमान अनुवाद इकाई के भीतर दिखाई दे रहा है, यही कारण है कि MyPrint2 इसे एक्सेस कर सकता है।

0

दोनों फ़ंक्शन अलग-अलग ढेर बनाएंगे, इसलिए स्थैतिक हिस्सा अलग-अलग होगा। इसलिए यह संभव है।

+1

स्थानीय 'स्थिर int svar' में से कोई भी * स्टैक * पर आवंटित नहीं किया जाएगा (यदि ऐसी कोई अवधारणा है), प्रत्येक फ़ंक्शन बॉडी एक अलग ब्लॉक है, जो स्थानीय 'स्थिर 'चर के दायरे को सीमित करता है। संकलक यह सुनिश्चित करने के लिए एक नामकरण योजना का उपयोग करता है कि ये चर लिंक समय पर अलग हैं। – chqrlie

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