2011-03-10 16 views
10

जब मैं सी संकलन ++ के साथ "चेतावनी स्तर 4" विजुअल C++ 9 के साथ कोड निम्नलिखित:"जबकि (सत्य)" के लिए एक कंपाइलर चेतावनी जारी करने का मुद्दा क्या है और "के लिए (;;)" के लिए जारी नहीं किया जा रहा है?

while(true) { 
    //loop body with break on certain condition 
} 

और निम्नलिखित:

for(; true;) { 
    //same loop body 
} 

दोनों ट्रिगर C4127: conditional expression is constant चेतावनी लेकिन निम्नलिखित:

for(; ;) { 
    //same loop body 
} 

चेतावनी के बिना संकलित करता है।

यह अंतर, खासकर दूसरे और तीसरे संस्करण के बीच क्यों?

+1

क्योंकि तीसरे कथन में कोई सशर्त अभिव्यक्ति नहीं है ... जबकि यह दूसरे और तीसरे में है .... कंपाइलर बिना किसी के सशर्त अभिव्यक्ति के बारे में चेतावनी कैसे उत्पन्न कर सकता है? –

+1

मैं आमतौर पर '#pragma चेतावनी' के साथ C4127 को अक्षम कर देता हूं, खासकर जब बूस्ट का उपयोग करता हूं। –

+0

संबंधित: http://stackoverflow.com/questions/224421/constant-value-in-conditional-expression – CesarB

उत्तर

6

कारण सरल है, हालांकि बेवकूफ है।

यह अनंत लूप का निदान करने के लिए महत्वपूर्ण है, लेकिन इस तरह स्पष्ट नहीं हो सकता है:

while(i >= 0) { --i; } // infinite if i unsigned 

while(SOME_MACRO(i)) // err, depends on the expansion of macros 

यह एक संकलक एक अनुलापिक परीक्षण के लिए एक चेतावनी का उत्पादन करने के लिए एक महान विशेषता है, कि एक परीक्षण है कि पता चला है है या तो हमेशा सत्य या हमेशा झूठी होने के लिए, क्योंकि जब यह एक मैक्रो विस्तार से या एक निर्भर संदर्भ में आता है तो यह स्पष्ट नहीं है।

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

4

for (;;) निर्माण जानबूझकर कोड "अंतहीन" लूप का कैननिकल तरीका है। मैं कल्पना कर सकता था कि संकलक डिजाइनर इसके लिए चेतावनी उत्पन्न नहीं करना चाहते थे।

+6

मैं कहूंगा कि कारण अन्य तरीका है - यह कैननिकल * है * क्योंकि यह किसी निश्चित पर चेतावनी जारी नहीं करता है लोकप्रिय कंपाइलर श्रृंखला। –

+0

यदि आप वीएस के अलावा अन्य कंपाइलर्स शामिल करते हैं तो मुझे यह भी कैननिकल नहीं लगता है। मुझे नहीं लगता कि जीसीसी इस पर चेतावनी देता है? –

+0

@jk: आप वास्तव में सही हैं, जीसीसी इन संरचनाओं में से किसी एक के बारे में चेतावनी नहीं देता है। मैंने इसके लिए परीक्षण नहीं किया, बस अनुमान लगाया। – DevSolar

10

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

4

कोई बात नहीं। सब के बाद, भाषा विनिर्देश कहते हैं ($ 6.5.3/2),

या तो या हालत और अभिव्यक्ति की दोनों छोड़ा जा सकता है। ए गायब स्थिति को अंतर्निहित करती है जबकि धारा के बराबर होती है जबकि (सत्य)।

तो for (; ;) भी मानक के अनुसार while(true) के बराबर है। इसलिए, मुझे कोई कारण नहीं दिख रहा है कि संकलक को एक मामले में चेतावनी क्यों देनी चाहिए, लेकिन दूसरे में नहीं!

-

संकलक चेतावनी दे करने का फैसला करता है, तो मेरी राय में, संकलक चेतावनी जब हालत लापता के रूप में जब यह मौजूद है, तो यह है कि चेतावनी के रूप में व्याख्या की जाएगी करने का विरोध किया है देना चाहिए प्रोग्रामर के लिए संकेत प्रोग्रामर के लिए इरादे स्पष्ट रूप से और स्पष्ट रूप से का उल्लेख करने के लिए।

मेरा मतलब है, for (;;)अधिक स्पष्टfor (;true;) में हालत का उल्लेख की तुलना में एक टाइपो होने की संभावना है। उत्तरार्द्ध प्रोग्रामर के स्पष्ट और स्पष्ट इरादे को बताता है। स्टीव टिप्पणी में कहते हैं:

एक पूर्णांक मूल्य y के लिए, चार एक्स = y बराबर चार के लिए एक्स = (चार) y है, लेकिन आप एक अंतर्निहित संकुचन पर रूपांतरण के लिए एक चेतावनी चाहते हो सकता है पहले लेकिन दूसरा नहीं।

तो स्पष्ट इरादे को चेतावनी नहीं मिलनी चाहिए, जबकि निहित इरादा प्राप्त करना चाहिए!

+0

@ डाउनवॉटर: क्यों डाउनवोट? – Nawaz

+2

मेरा डाउनवोट नहीं, लेकिन मुझे लगता है कि समानता एक लाल हेरिंग है। एक और उदाहरण के लिए, मानक 'if (x = y)' के अनुसार 'if ((x = y)) के बराबर है, लेकिन जीसीसी पूर्व के लिए चेतावनी देता है और बाद वाले नहीं। एक इंट वैल्यू वाई के लिए, 'char x = y' 'char x = (char) y' के समतुल्य है, लेकिन हो सकता है कि आप पहले पर एक संकीर्ण संकुचन रूपांतरण के लिए चेतावनी चाहें लेकिन दूसरा नहीं। –

+2

सच है लेकिन मुझे यह विचार मिलता है कि जबकि (सत्य) एक टाइपो होने की संभावना है जो असुविधाजनक हो। इमोहो वीएस बहुत अधिक उग्र है –

1

संभावित बग पकड़ने में मदद करने के लिए कंपाइलर चेतावनी यहां हैं। while लूप में हमेशा true स्थिति का उपयोग करना संभवतः एक त्रुटि है। उदाहरण के लिए, निम्न कोड में, यह शायद एक बग है, और मैं संकलक इसके बारे में मुझे चेतावनी करना चाहते हैं:

unsigned int x; 
// ... 
while (x >= 0) { 
    // ... 
} 

ऐसी स्थिति में, अनुकूलित निर्माण में संकलक शर्त यह है कि संभवत: यह मान जाएगा हमेशा सत्य है (क्योंकि एक हस्ताक्षरित पूर्णांक 0 से छोटा नहीं हो सकता है)। इसलिए while लूप में हमेशा true स्थिति का पता लगाने की आवश्यकता है। मुझे लगता है कि जिसने इस तरह की त्रुटि का पता लगाया है, while (true) केस विशेष मामला नहीं था, क्योंकि for (;;) के साथ अनंत लूप करने का एक आसान तरीका है।

आप here, कैसे दृश्य स्टूडियो में एक चेतावनी या नहीं जोड़ने के लिए निर्णय पढ़ सकते हैं, लिया जाता है (उदाहरण के C# के बारे में हैं, लेकिन मुझे लगता है कि टीम C++ में चेतावनी के लिए अंगूठे का यही नियम है)।

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