एक अस्थिर चर घोषित करने का क्या मतलब है?


9

कई निम्न स्तर के प्रोग्राम मेमोरी मैपिंग और इस तरह के प्रकारों के लिए अस्थिर कीवर्ड का उपयोग करते हैं, हालांकि मैं उलझन में हूँ कि यह पृष्ठभूमि में वास्तव में क्या करता है। दूसरे शब्दों में, इसका क्या मतलब है जब संकलक मेमोरी एड्रेस को "ऑप्टिमाइज़ करना" नहीं करता है?


1
यदि आप अपनी आयु किसी volatileचर से बाहर पढ़ रहे हैं और यह 5 कहती है, और आप इसे अगले वर्ष फिर से पढ़ते हैं, तो आपको 6. प्राप्त करने की गारंटी है
5gon12eder

@ 5gon12eder, मैं समझता हूं कि वाष्पशील का मतलब है कि कुछ तेजी से और आसान बदलाव के अधीन है, लेकिन यह कैसे काम करता है? : एस
विकटन

इसके अलावा, आपके संकलन झंडे के आधार पर, एक गैर-वाष्पशील चर 'आपके डिबगर में दिखाई दे सकता है (जैसे कि आप उदाहरण के लिए C कोड + ग्रहण + gdb का उपयोग कर रहे हैं), जैसे:' अनुकूलित आउट मान 'क्योंकि चर का मान अब है एक रजिस्टर में कहीं। यदि आप असेंबली लैंग्वेज डिबगिंग टूल / फीचर्स का उपयोग करना नहीं जानते हैं, तो बस अस्थिर चर का उपयोग करके अपने वैरिएबल की घोषणा करें।

जवाबों:


11

volatile इसका मतलब है कि कुछ अन्य प्रोसेसर या I / O डिवाइस या कुछ आपके नीचे से परिवर्तनशील चर को बदल सकते हैं।

एक साधारण वैरिएबल के साथ, आपके प्रोग्राम के चरण ही एकमात्र ऐसी चीज है जो इसे बदल देगी। उदाहरण के लिए यदि आप 5एक चर से पढ़ते हैं और आप इसे नहीं बदलते हैं, तो यह अभी भी शामिल होगा 5। चूँकि आप उस पर भरोसा कर सकते हैं, इसलिए अगली बार जब आप इसका उपयोग करना चाहते हैं तो अगली बार चर को पढ़ने के लिए समय नहीं निकालना पड़ेगा। C ++ कंपाइलर कोड उत्पन्न करने के लिए स्मार्ट है जो सिर्फ याद रखता है 5

लेकिन आप इसे पढ़ सकते हैं 5, फिर शायद सिस्टम डिस्क से डेटा को उस मेमोरी में लोड करता है, इसे बदल रहा है 500। यदि आप चाहते हैं कि आपका कार्यक्रम नए सिरे से पढ़ा जाए 500, तो आपको पहले से पढ़े गए का उपयोग करने के बारे में समझदार नहीं होने के लिए कंपाइलर की आवश्यकता है 5। आपको हर बार मान को पुनः लोड करने के लिए इसे बताने की आवश्यकता है। वही volatileकरता है।

5 साल के बच्चों के लिए एक सादृश्य
चलो मान लें कि आपने एक मेज पर कागज की एक बड़ी शीट रखी है। कागज के एक कोने में, आप, चल रहे एक खेल के वर्तमान स्कोर लिख 3 to 4। फिर आप तालिका के विपरीत पक्ष पर जाते हैं और खेल के बारे में एक कहानी लिखना शुरू करते हैं। आपका मित्र जो गेम देख रहा है, गेम के बढ़ने पर उस कोने में स्कोर अपडेट करता है। वह मिटाती है 3 to 4और लिखती है 3 to 5

जब आप अपनी कहानी में गेम स्कोर डालने जाते हैं, तो आप या तो:

  1. नीचे पढ़ा गया अंतिम अंक लिखिए, 3 to 4यह मानते हुए कि यह नहीं बदला (या अगर ऐसा किया था तो दिमाग नहीं), या
  2. वर्तमान अंक (जो 3 to 5अब होता है ) को पढ़ने के लिए तालिका के विपरीत दिशा में घूमें , और वापस चलें। एक volatileचर कैसे काम करता है।

11

volatile दो चीजों का मतलब है:

  1. चर का मान आपके किसी भी कोड के बिना इसे बदल सकता है। इसलिए जब भी संकलक चर का मान पढ़ता है, तो यह नहीं मान सकता है कि यह पिछली बार पढ़ी गई सामग्री के समान है, या यह कि यह पिछले मूल्य के रूप में ही संग्रहीत है, लेकिन इसे फिर से पढ़ा जाना चाहिए।

  2. एक अस्थिर चर के लिए एक मूल्य संग्रहीत करने का कार्य एक "साइड इफेक्ट" है जो बाहर से मनाया जा सकता है, इसलिए संकलक को एक मूल्य संग्रहीत करने के कार्य को हटाने की अनुमति नहीं है; उदाहरण के लिए यदि दो मान एक पंक्ति में संग्रहीत किए जाते हैं, तो संकलक को वास्तव में दो बार मूल्य को संग्रहीत करना होगा।

उदहारण के लिए:

i = 2; 
i = i; 

कंपाइलर को नंबर दो को स्टोर करना चाहिए , वेरिएबल i को पढ़ना चाहिए , उस वैरिएबल को स्टोर करना चाहिए जिसे वह i में पढ़ता है।

एक और स्थिति है: यदि कोई फ़ंक्शन उपयोग करता है setjmpऔर फिर longjmpकॉल किया जाता है, तो फ़ंक्शन के सभी अस्थिर स्थानीय चर को अंतिम मान संग्रहीत करने की गारंटी दी जाती है - यह गैर-वाष्पशील स्थानीय चर के मामले में नहीं है।


यहां कुछ सूक्ष्म समस्याएं हैं। एक सूक्ष्म समस्या यह है कि आपने अस्थिर रीडर्स को चर की विशेषता के रूप में दिखाया है जब वास्तव में वे इस बात की विशेषता है कि चर कैसे एक्सेस किया जाता है । यदि हमारे पास वैरिएबल iऔर वैल्यू है pi = &i, तो x = *piएक रीड से करता है i, लेकिन उस रीड को वाष्पशील शब्दार्थ होने की गारंटी नहीं है।
एरिक लिपर्ट

1
@EricLippert: अगर iघोषित किया गया है volatile int iतो घोषित किया piजाना चाहिए volatile int *pi, किस मामले *piमें एक अस्थिर पहुंच है, नहीं?
जॉन प्यार्डी

2

सार स्पष्टीकरण
C और C ++ दोनों में एक अमूर्त मशीन की अवधारणा है । जब कोड कुछ चर के मूल्य का उपयोग करता है, तो अमूर्त मशीन का कहना है कि कार्यान्वयन को उस चर के मूल्य का उपयोग करना होगा। statement_A; statement_B; statement_C;निर्दिष्ट क्रम में फ़ॉर्म के कोड को निष्पादित किया जाना है। उन तीनों कथनों के लिए सामान्य अभिव्यक्तियाँ प्रत्येक बार होने वाली घटनाओं की पुनः गणना की जानी चाहिए।

अमूर्त मशीनों के अनुसार statement_A; statement_B; statement_C;, बयानों के अनुक्रम को देखते हुए , कार्यान्वयन को पहले statement_Aअपनी संपूर्णता में प्रदर्शन करना चाहिए , फिर statement_B, और अंत में statement_C। कार्यान्वयन यह याद नहीं रख सकता है कि आपने age5 का मान असाइन किया है। हर बयान जो संदर्भ के ageबजाय उस चर के मूल्य तक पहुंचना चाहिए।

volatileयदि अमूर्त मशीन विनिर्देशों के अनुसार C या C ++ कोड को सख्ती से क्रियान्वित किया जाता है, तो कीवर्ड की कोई आवश्यकता नहीं होगी । सी और सी ++ एब्सट्रैक्ट मशीनों में रजिस्टरों की कोई अवधारणा नहीं है, आम सबटेक्शंस की कोई अवधारणा नहीं है, और निष्पादन आदेश सख्त है।

दोनों भाषाओं में भी अगर-जैसे नियम हैं। एक कार्यान्वयन मानक के साथ अनुपालन है जब तक कि कार्यान्वयन व्यवहार करता है जैसे कि उसने अमूर्त मशीन विनिर्देश के अनुसार चीजों को निष्पादित किया था। संकलक मान सकता है कि गैर-वाष्पशील चर असाइनमेंट के बीच मूल्यों को नहीं बदलते हैं। इसलिए जब तक यह as-ifनियम को नहीं तोड़ता statement_A; statement_B; statement_C;है statement_C, तब तक के भाग को निष्पादित करके अनुक्रम लागू किया जा सकता है , फिर का हिस्सा statement_A, फिर सभी का statement_B, फिर बाकी का statement_A, और अंत में बाकी का statement_C

उन के रूप में करता है, तो नियमों पर लागू नहीं हैं volatileचर। volatileचर और कार्यों के संबंध में , एक क्रियान्वयन को वही करना है जो आपने इसे करने के लिए कहा था, और वास्तव में इस क्रम में आपने इसे चीजों को करने के लिए कहा था।

अमूर्त मशीन विनिर्देश के लिए एक नकारात्मक पहलू है: यह धीमा है। अन्य भाषाओं की तुलना में C और C ++ का एक सकारात्मक पहलू यह है कि वे काफी तेज हैं। यह नहीं होगा अगर इन अमूर्त मशीनों के अनुसार कोड निष्पादित किया गया था। के रूप में करता है, तो नियम क्या सक्षम C और C ++ इतनी तेजी से हो रहे हैं।

ELI5 उत्तर

इसका क्या मतलब है जब संकलक मेमोरी एड्रेस को "ऑप्टिमाइज़ करना" नहीं करता है?

मेमोरी एड्रेस को "ऑप्टिमाइज़ करना" एक उन्नत अवधारणा है, कुछ ऐसा जो पांच साल पुरानी क्षमताओं के दायरे में नहीं है। आज्ञाकारी पाँच वर्ष के बच्चे वही करेंगे जो आप उन्हें करने के लिए कहेंगे, और नहीं, कम नहीं। इसके साथ volatile, आप कार्यान्वयन को पांच की तरह कार्य करने के लिए कह रहे हैं: कोई सोच नहीं, कोई फैंसी अनुकूलन नहीं। इसके बजाय, कार्यान्वयन को वही करना होगा जो कोड इसे करने के लिए कहता है।


1

(गैर-) अस्थिर संकलक के लिए एक संकेत है कि कोड का अनुकूलन कैसे करें (उत्पन्न विधानसभा-कोड बिंदु से):

  • गैर वाष्पशील का अर्थ है कि आपका वर्तमान संकलक यह तय करता है कि चर कहाँ स्थित होगा या चर-मान का मान उप-क्षेत्र में कैसे रखा जाएगा?
    • एक निश्चित मेमोरी एड्रेस में,
    • स्टैक पर [प्रोसेसर वर्तमान स्टैकपॉइंट के सापेक्ष],
    • ढेर पर [प्रोसेसर वर्तमान बेसपॉइंटर के सापेक्ष],
    • एक प्रोसेसर रजिस्टर में,
    • ...
  • वाष्पशील का मतलब है कि कंपाइलर चर का अनुकूलन नहीं कर सकता क्योंकि मुख्य-सीपीयू-एस नियंत्रक (यानी एक अलग io- प्रोसेसर) के बाहर कुछ और इस मूल्य को बदल सकता है।

0

उत्तर काफी सुसंगत लग रहे हैं लेकिन एक महत्वपूर्ण बिंदु गायब है। आप संकलक को बता रहे हैं कि आप किस स्थान को आवंटित करना चाहते हैं और हर पहुंच के लिए, ORITE पढ़ें, आप चाहते हैं कि वह उस पहुंच का प्रदर्शन करे। हम इसे किसी कारण से उन एक्सेस या वैरिएबल को ऑप्टिमाइज़ करना नहीं चाहते हैं।

हां, एक कारण यह है कि कोई और हमारे लिए उस मूल्य को बदल सकता है। दूसरा कारण यह है कि हम किसी और के लिए उस मूल्य को बदल सकते हैं। यह कोई और है जो इसे हमारे लिए बदलता है या जो हम इसे बदल रहे हैं वह हार्डवेयर / तर्क या सॉफ्टवेयर हो सकता है। इसका उपयोग अक्सर नंगे धातु एम्बेडेड कार्यक्रमों में नियंत्रण और स्थिति रजिस्टर तक पहुंच को परिभाषित करने, हार्डवेयर से लिखने या पढ़ने के लिए किया जाता है। साथ ही साथ सॉफ्टवेयर से बात करने वाले सॉफ्टवेयर ने अन्य उत्तरों में समझाया।

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

अवसर पर, आप देखेंगे कि यह केवल समय को जलाने के लिए उपयोग किया जाता है, एक प्राथमिक एलईडी ब्लिंकर, नंगे धातु की नमस्ते दुनिया, एक चर के लिए एक अस्थिर का उपयोग कर सकती है जो कि कुछ बड़ी संख्या में गिना जाता है ताकि मानव आंखों को देखने के लिए समय जला सके। परिवर्तन की स्थिति। अधिक उन्नत उदाहरण तो समय को जलाने के लिए टाइमर या अन्य घटनाओं का उपयोग करना।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.