C ++ में वाष्पशील बनाम उत्परिवर्तनीय


85

मेरे पास वाष्पशील और उत्परिवर्तित के बीच अंतर के बारे में एक प्रश्न है। मैंने देखा कि दोनों का मतलब है कि इसे बदला जा सकता है। और क्या? क्या ये एक ही चीज हैं? क्या फर्क पड़ता है? वे कहां लागू हैं? दो विचार क्यों प्रस्तावित हैं? उन्हें अलग-अलग तरीके से कैसे उपयोग करें?

बहुत बहुत धन्यवाद।

जवाबों:


112

किसी mutableफ़ील्ड को constपॉइंटर या संदर्भ या किसी ऑब्जेक्ट के माध्यम से एक्सेस की गई ऑब्जेक्ट में भी बदला जा सकता है const, इसलिए कंपाइलर इसे R / O मेमोरी में स्‍टैश नहीं करना जानता है। एक volatileस्थान वह है जिसे कोड द्वारा परिवर्तित किया जा सकता है, जिसके बारे में कंपाइलर को पता नहीं है (जैसे कि कुछ कर्नेल-स्तरीय ड्राइवर), इसलिए कंपाइलर यह नहीं जानता है कि उदाहरण के लिए अमान्य मान के तहत उस मान के रजिस्टर असाइनमेंट को समायोजित करें जो कि मान नहीं हो सकता है " बदल गया "चूंकि यह आखिरी बार उस रजिस्टर में लोड किया गया था। बहुत अलग तरह की जानकारी संकलक को दी जा रही है जो बहुत अलग प्रकार के अमान्य अनुकूलन को रोकती है।


13
volatileसीपीयू को शामिल नहीं करने वाली प्रक्रियाओं द्वारा वस्तुओं को भी बदला जा सकता है। उदाहरण के लिए, एक संचार परिधीय में एक बाइट्स-प्राप्त रजिस्टर बाइट की प्राप्ति पर खुद को बढ़ा सकता है (और यह भी एक बाधा को ट्रिगर कर सकता है)। एक अन्य उदाहरण एक लंबित-बाधित झंडे एक परिधीय में रजिस्टर है।
माइक डीस्मोन

55
इसके अलावा, volatileकेवल इसका मतलब यह नहीं है कि ऑब्जेक्ट संकलक के ज्ञान के बाहर बदल सकता है - इसका मतलब यह भी है कि ऑब्जेक्ट को लिखने वाले को संकलक द्वारा समाप्त नहीं किया जा सकता है, भले ही वे लिखते हैं कि बेकार प्रतीत होता है। उदाहरण के लिए: x = 1; x = 0; यदि xअस्थिर है, तो संकलक को दोनों लिखने के संचालन का उत्सर्जन करना होगा (जो हार्डवेयर स्तर पर महत्वपूर्ण हो सकता है)। हालांकि, एक गैर-वाष्पशील वस्तु के लिए, कंपाइलर को लिखने के साथ परेशान करने के लिए नहीं चुना जा सकता है 1क्योंकि यह कभी भी उपयोग नहीं किया जाता है।
माइकल बूर

15
एक वस्तु दोनों को चिह्नित किया जा सकता है constऔर volatile! आप ऑब्जेक्ट को बदल नहीं सकते हैं, लेकिन इसे आपकी पीठ के पीछे बदला जा सकता है।
CTMacUser

2
@ डस्टर: सामान्य स्थिति एक हार्डवेयर डिवाइस रजिस्टर पर लिखने के लिए होती है।
माइकल बूर

5
@Destructor मान लीजिए कि आप एक एलईडी की स्थिति को नियंत्रित कर रहे हैं। 0 लिखें इसे बंद करें, 1 लिखें इसे चालू करें। अगर मुझे कुछ त्रुटि स्थिति को संप्रेषित करने के लिए एलईडी को फ्लैश करने की आवश्यकता है, लेकिन कंपाइलर पिछले सभी को छोड़कर सभी राइट्स को ऑप्टिमाइज़ करने का फैसला करता है, क्योंकि किसी भी मूल्य का उपयोग नहीं किया जा रहा है, तो एलईडी कभी नहीं चमकता है और जिस व्यवहार की मुझे इच्छा है, वह एहसास नहीं है ।
इहानी

28

mutable: परिवर्तनशील कीवर्ड किसी भी संलग्न कॉन्स्टैंट कथन को ओवरराइड करता है। एक कांस्टेबल ऑब्जेक्ट के एक परिवर्तनशील सदस्य को संशोधित किया जा सकता है।

volatile: वाष्पशील खोजशब्द एक कार्यान्वयन-निर्भर संशोधक है, जिसका उपयोग चर घोषित करते समय किया जाता है, जो संकलक को उन चरों के अनुकूलन से रोकता है। अस्थिर का उपयोग उन चर के साथ किया जाना चाहिए, जिनका मूल्य अप्रत्याशित तरीकों से बदल सकता है (अर्थात एक बाधा के माध्यम से), जो कि अनुकूलन के साथ संघर्ष कर सकता है जो संकलक प्रदर्शन कर सकता है।

स्रोत


आपने कहा कि Volatile should be used with variables whose value can change in unexpected waysक्या हम इसे यादृच्छिक के साथ उपयोग करना पसंद करेंगे?
आसिफ मुश्ताक

@AsifMushtaq मान नहीं। तरीके। उत्परिवर्तनीय प्रभाव आपके द्वारा लिखे गए अनुज्ञाओं पर प्रभाव डालता है। तो आप एक const ptr, या const संदर्भ के माध्यम से चर का उपयोग कर सकते हैं। क्या होगा अगर आपका कोड इसे बदल नहीं रहा है? कुछ संकलक कठबोली ptr या संदर्भ प्रकार की जाँच करते हैं? वह अस्थिर है। और अस्थिर भी कैश को मुख्य मेमोरी में वापस लिखने के लिए मजबूर करता है। तो यह बहु थ्रेडेड कोड के साथ एक बहुत उपयोग किया जाता है। :)
डैन

22

वे निश्चित रूप से एक ही बात नहीं कर रहे हैं। कांस्टेबल के साथ आपसी बातचीत। यदि आपके पास एक कास्ट पॉइंटर है, तो आप सामान्य रूप से सदस्यों को नहीं बदल सकते। म्यूटेबल उस नियम को एक अपवाद प्रदान करता है।

दूसरी ओर, वाष्पशील, प्रोग्राम द्वारा किए गए परिवर्तनों के लिए पूरी तरह से असंबंधित है। इसका मतलब है कि मेमोरी कंपाइलर के नियंत्रण से परे कारणों से बदल सकती है, इसलिए कंपाइलर को हर बार मेमोरी एड्रेस को पढ़ना या लिखना पड़ता है और सामग्री को एक रजिस्टर में कैश नहीं कर सकता है।


"अस्थिर, दूसरी ओर, प्रोग्राम द्वारा किए गए परिवर्तनों के लिए पूरी तरह से असंबंधित है ..." - हम्म, एक सदस्य को अस्थिर बनाएं और देखें कि संकलन के दौरान क्या टूटता है। तथ्य के बाद अस्थिरता जोड़ने की कोशिश करना बहुत कुछ है तथ्य के बाद कास्ट जोड़ने की कोशिश करना ... दर्दनाक।
jww 15'15

@jww: यह कार्यक्रम द्वारा किए गए लेखन के लिए पूरी तरह से असंबंधित है। आप एक प्रकार के ऑब्जेक्ट का पता ले सकते हैं T, और इसे एक में स्टोर कर सकते हैं और इसे const T*पढ़ सकते हैं। यदि आप उस वस्तु को बनाते हैं volatile, तो उसके पते को संग्रहीत const T*करना विफल हो जाएगा, भले ही आप कभी भी लिखने की कोशिश नहीं कर रहे हों। volatileऔर प्रोग्राम कोड से परिवर्तन / संशोधन / मेमोरी पूरी तरह से ऑर्थोगोनल हैं।
बेन वोइगट

17

अंतर की सोच का एक कच्चा लेकिन प्रभावी तरीका है:

  • संकलक जानता है कि एक उत्परिवर्तनीय वस्तु कब बदलती है।
  • संकलक को पता नहीं चलता है कि कब कोई अस्थिर वस्तु बदलती है।

1
कि नस में: volatilebytes_received, mutableREFERENCE_COUNT।
माइक डीमोन

11

एक वैरिएबल मार्क mutableइसके लिए घोषित विधि में संशोधित करने की अनुमति देता हैconst

एक चर चिह्नित volatileकंपाइलर को बताता है कि उसे हर बार कोड को पढ़ना / लिखना होगा, यह आपका कोड भी बताता है (यानी यह कैंटीन चर तक पहुंच को अनुकूलित करता है)।


4

मैं जोड़ना चाहूंगा कि मल्टीथ्रेडिंग एप्लिकेशन से निपटने के दौरान वाष्पशील भी बहुत उपयोगी है, अर्थात, आपके पास आपका मुख्य धागा (जहां मुख्य () रहता है) है और आप एक कार्यकर्ता थ्रेड को स्पॉन करते रहेंगे जो चर "app_running" सच है। मुख्य () नियंत्रित करता है कि क्या "app_running" सही है या गलत, इसलिए यदि आप "app_running" की घोषणा के लिए वाष्पशील विशेषता नहीं जोड़ते हैं, यदि संकलक माध्यमिक थ्रेड द्वारा चलाए गए कोड में "app_running" तक पहुंच का अनुकूलन करता है, तो मुख्य ( ) "app_running" को गलत में बदल सकता है लेकिन द्वितीयक धागा चालू रहेगा क्योंकि मान कैश हो गया है। मैंने Linux और VisualC ++ पर gcc का उपयोग करके समान व्यवहार देखा है। एक "अस्थिर" विशेषता "app_running" घोषणा में डाल समस्या को हल किया। इसलिए,


1
नहीं! यह एक सामान्य गलतफहमी है। C ++ 11 और C11 ने इस उद्देश्य के लिए एटॉमिक्स की शुरुआत की stackoverflow.com/questions/8819095/…
KristianR
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.