इस सरल कोड पर विचार करें:
void g();
void foo()
{
volatile bool x = false;
if (x)
g();
}
आप संभावित कॉल को न तो देख सकते हैं gccऔर न ही clangऑप्टिमाइज़ कर सकते हैं g। यह मेरी समझ में सही है: अमूर्त मशीन यह मानने के लिए है कि volatileचर किसी भी क्षण (उदाहरण के लिए हार्डवेयर-मैप किए जाने के कारण) बदल सकते हैं, इसलिए चेक falseमें इनिशियलाइज़ेशन को लगातार मोड़ना ifगलत होगा।
लेकिन MSVC कॉल को gपूरी तरह से समाप्त कर देता है ( volatileहालांकि पढ़ता है और हालांकि लिखता है !)। क्या यह मानक-अनुरूप व्यवहार है?
पृष्ठभूमि: मैं कभी-कभी इस तरह के निर्माण का उपयोग फ्लाई-ऑन डिबगिंग आउटपुट को चालू / बंद करने में सक्षम होने के लिए करता हूं: कंपाइलर को हमेशा मेमोरी से मूल्य पढ़ना पड़ता है, इसलिए डिबगिंग के दौरान परिवर्तनशील / मेमोरी को नियंत्रण प्रवाह को तदनुसार संशोधित करना चाहिए। । MSVC आउटपुट मान को फिर से पढ़ता है लेकिन इसे अनदेखा करता है (संभवतः निरंतर तह और / या मृत कोड उन्मूलन के कारण), जो निश्चित रूप से मेरे इरादों को यहाँ पराजित करता है।
संपादन:
रीड एंड एलिमिनेशन के उन्मूलन
volatileपर यहां चर्चा की गई है: क्या स्थानीय कंपाइलर वैरिएबल को ऑप्टिमाइज़ करने के लिए कंपाइलर की अनुमति है? (धन्यवाद नाथन!)। मुझे लगता है कि मानक बहुतायत से स्पष्ट है कि उन रीड और राईट चाहिए होता है। लेकिन यह चर्चा कवर नहीं करती है कि संकलक के लिए यह कानूनी है कि वह पढ़े गए परिणामों का परिणाम ले और उसके आधार पर अनुकूलन करे। मुझे लगता है कि यह है मानक के तहत अनिर्दिष्ट है, लेकिन अगर किसी ने मुझे गलत साबित किया तो मुझे खुशी होगी।मैं
xइस मुद्दे को साइड-स्टेप करने के लिए एक गैर-स्थानीय चर बना सकता हूं । यह प्रश्न जिज्ञासा से अधिक है।