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