2012-03-29 15 views
57

volatile संकलक को संदर्भित करने के लिए संकलक को बताना है, ताकि प्रत्येक पढ़ने/लिखने में रजिस्टर में संग्रहीत मूल्य का उपयोग न किया जाए लेकिन वास्तविक स्मृति पहुंच हो। मैं समझ सकता हूं कि यह कुछ सामान्य चर के लिए उपयोगी है, लेकिन यह समझ में नहीं आता कि volatile एक सूचक को कैसे प्रभावित करता है।एक पॉइंट-टू-अस्थिर सूचक क्यों है, जैसे "अस्थिर int * p", उपयोगी?

volatile int *p = some_addr; 
int a = *p; // CPU always has to load the address, then does a memory access anyway, right? 

अगर यह int *p = some_addr घोषित किया गया है क्या अंतर है?

उत्तर

101

रूप

volatile int* p; 

का एक सूचक एक int के लिए सूचक है कि संकलक volatile के रूप में इलाज नहीं है। इसका मतलब यह है कि संकलक मान लेगा कि यह चर के लिए संभव है कि p स्रोत कोड में कुछ भी नहीं होने के बावजूद यह बदल सकता है कि यह हो सकता है। उदाहरण के लिए, यदि मैं नियमित पूर्णांक को इंगित करने के लिए p सेट करता हूं, तो हर बार जब मैं *p पढ़ता या लिखता हूं तो संकलक को पता है कि मान अप्रत्याशित रूप से बदल सकता है।

एक volatile int* के लिए एक और उपयोग के मामले नहीं है: आप यह घोषणा करते हैं एक intvolatile के रूप में है, तो आप एक नियमित रूप से int* साथ इस पर बात नहीं करना चाहिए। उदाहरण के लिए, यह एक बुरा विचार है:

volatile int myVolatileInt; 
int* ptr = &myVolatileInt; // Bad idea! 

इस का कारण यह सी संकलक नहीं रह गया है याद करते हैं कि उस चर पर ptrvolatile है द्वारा इशारा किया, तो यह गलत तरीके से एक रजिस्टर में *p का मूल्य कैश हो सकता है । वास्तव में, सी ++ में, उपर्युक्त कोड एक त्रुटि है। इसके बजाय, आप

volatile int myVolatileInt; 
volatile int* ptr = &myVolatileInt; // Much better! 

लिखना चाहिए अब, संकलक याद है एक volatile int पर ptr अंक, तो यह (या नहीं! चाहिए) नहीं होगा अनुकूलन करने के लिए कोशिश *ptr के माध्यम से पहुँचता है।

एक आखिरी विस्तार - आपके द्वारा चर्चा की गई पॉइंटर volatile int पर सूचक है। तुम भी ऐसा कर सकते हैं:

int* volatile ptr; 

यह कहा गया है कि सूचक हीvolatile है, जिसका अर्थ है कि संकलक स्मृति में सूचक कैश करने के लिए प्रयास करें या सूचक मूल्य का अनुकूलन करने की कोशिश नहीं करनी चाहिए क्योंकि सूचक ही कुछ और (हार्डवेयर, एक और धागा, आदि) आप इन एक साथ गठजोड़ कर सकते हैं द्वारा पुन: असाइन हो सकता है अगर आप इस जानवर प्राप्त करना चाहते हैं:

volatile int* volatile ptr; 

यह कहा गया है कि दोनों सूचक और pointee अनपेक्षित रूप से बदल हो सकता है । संकलक सूचक को अनुकूलित नहीं कर सकता है, और यह अनुकूलित नहीं कर सकता कि क्या हो रहा है।

आशा है कि इससे मदद मिलती है!

+0

मुझे लगता है कि आपका मतलब है "आपको इसे नियमित int * के साथ इंगित नहीं करना चाहिए" – markgz

+0

@ markgz- Whoops! हाँ, यह सही है। फिक्स्ड। – templatetypedef

+0

मुझे लगता है कि यह सी में भी एक त्रुटि है, लेकिन सी कंपाइलर्स टाइप मिस्चैच के बारे में शिकायत करने के लिए कम प्रवण हैं। –

6

यह कोड volatile int *p = some_addrvolatile int पर एक पॉइंटर घोषित करता है। सूचक स्वयं volatile नहीं है।

अप्रत्याशित घटना है कि आप सूचक की जरूरत पूर्णांक के रूप में भी अस्थिर होने के लिए, आप का उपयोग करने की आवश्यकता होगी:

volatile int * volatile p; 

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

+2

उदाहरण: मैं मैं आईएसआर कोड में 'अस्थिर uint8_t * अस्थिर पीडीटा' का उपयोग कर रहा हूं जो सूचक और डेटा को इंगित करता है। सूचक मुख्य कोड द्वारा निर्धारित किया जाता है, और बाद में पॉइंटर और डेटा दोनों पढ़े जाते हैं। – Christoph

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