लूप के लिए अपने घुंघराले ब्रेसिज़ के अंदर


117

मैं इस लूप लेआउट के लिए आया हूं:

#include <iostream>
int main()
{
    {
        for (int i = 0; i != 10; ++i)
        {
            std::cout << "delete i->second;" << std::endl;
        }
    }

    {
        for (size_t i = 0; i < 20; ++i)
        {
            std::cout << "delete m_indices[i];" << std::endl;
        }
    }
    return 0;
}

मैं सोच रहा था कि ब्रेसिज़ की यह अतिरिक्त परत किस लिए है? यह हमारे कोड बेस में कुछ बार दिखाई देता है।


47
वे आपके द्वारा पोस्ट किए गए कोड स्निपेट में पूरी तरह से शानदार हैं
EdChum

25
इस कोड के साथ क्या संकलक का उपयोग किया गया है? विशेष रूप से वीएस 6 का उपयोग किया गया था?
UKMonkey

5
@ संपादित करें अब आपके संपादन के साथ यह बहुत स्पष्ट है। ऐसा लगता है कि सही उत्तर UKMonkey द्वारा प्रदान किया गया है। आधुनिक सी ++ संकलक के साथ आप घुंघराले ब्रेसिज़ को सरल रूप से छोड़ सकते हैं।
Jabberwocky

8
वैकल्पिक रूप से, यह कोड उत्पन्न किया जा सकता है (किसी व्यक्ति को सिर्फ
रैपसोडी के

4
एक संभावित कारण यह है कि कोड एक बार था (या भविष्य में करने का इरादा है) OpenMP समानांतर निर्देश।
jamesqf

जवाबों:


286

एक बार, कई चंद्रमाओं से पहले, वीएस 6 मौजूद था और लोकप्रिय था। यह हालांकि C ++ मानकों की संख्या के अनुरूप विफल रहा; जो उस समय उचित था, क्योंकि यह उसी वर्ष (ठीक उसी वर्ष) से ​​पहले जारी किया गया था, जो आधिकारिक तौर पर जारी किया गया था; हालाँकि इसने मानक के मसौदे का पालन किया जहाँ तक मैं जागरूक हूँ।

ड्राफ्ट और आधिकारिक मानक के बीच परिवर्तित होने वाले मानकों में से एक, पहले खंड में निर्मित लूप चर के लिए जीवनकाल था; संकलन के लिए निम्नलिखित कोड के लिए अग्रणी

{
    for (int i=0; i<1; ++i){}
    for (int i=0; i<2; ++i){}
}

क्योंकि iलूप के लिए दूसरे द्वारा पुनर्परिभाषित किया गया था।

जबकि अन्य कंपाइलरों को भी इस बग का सामना करना पड़ा; मैं वीएस 6 एक को उजागर करता हूं क्योंकि यह मानक जारी होने के बाद कई वर्षों तक दृश्य स्टूडियो का एकमात्र संस्करण रहा, लेकिन इस विशेष मुद्दे के लिए कभी भी अपडेट जारी नहीं किया; इसका अर्थ है कि इसका अधिक महत्वपूर्ण प्रभाव पड़ा।

इसका एक समाधान यह है कि आप लूप के लिए पूरे को अपने दायरे में मजबूर करें, जैसा आपने दिखाया है।


49
कि @bolov, VS2015 में स्थापित करने के लिए "नहीं" "के लिए लूप स्कोप में सेना अनुरूपता" को देखने के लिए VS6 को खोजने की कोई ज़रूरत नहीं है, और आनंद ;-)
एलेन

5
@alain "विकल्प 'Zc: forScope-' को हटा दिया गया है और भविष्य के रिलीज़ में हटा दिया जाएगा" और बिना किसी समस्या के संकलन करता है ... मैं दुखी हूँ
bolov

7
संस्करण 2.7 से पहले जीसीसी ने भी इस व्यवहार का प्रदर्शन किया। देखें docs.freebsd.org/info/g++FAQ/g++FAQ.info.for_scope.html
जेरेमी

5
जब वीएस 6 को पहली बार जारी किया गया था तो @ डैमोन यह नहीं था; हालाँकि जब मानक बदल गए, तो उनके अनुरूप एक अपडेट कभी जारी नहीं किया गया। VS6 मानकों में बदलाव के बाद कुछ वर्षों तक लोकप्रिय रहा।
UKMonkey

7
एक पुराने Microsoft कंपाइलर के एक पाप के लिए यह करना फर्जी है। यह व्यवहार वास्तव में C ++ मानकों के मसौदे की एक विशेषता थी, और कई संकलक ने ऐसा किया (न केवल Microsoft संकलक)। मेमोरी से, इसे 1995 के दौरान एक ड्राफ्ट में बदल दिया गया था, चर को लूप में स्थानीय बनाने के लिए - पहले सी ++ मानक से लगभग तीन साल पहले। इसलिए 1996 में सबसे ज्यादा C ++ कंपाइलर (लगभग) ने इस तरह काम किया।
पीटर

15

{और }एक गुंजाइश बनाएगा और यदि आप इस दायरे में कुछ चर को परिभाषित करते हैं तो आप उन्हें बाहर से एक्सेस नहीं कर सकते। लेकिन forउस दायरे को पहले ही बना लें। इसलिए

{for(int i = 0; i < count; ++i){}} 

के समान है

for(int i = 0; i < count; ++i){}

लेकिन अगर आप उनके बीच कुछ परिभाषित करते हैं, तो एक अंतर है

{int a = 0; for(int i = 0; i < count; ++i){}}

इस उदाहरण में, aबाहर के दायरे से सुलभ नहीं होगा।


2

आपके विशेष उदाहरण में उनके लिए कोई कारण नहीं है।

कभी-कभी आप एक चर के लिए एक गुंजाइश बनाना चाहते हैं:

float average;
// ...

{
int sum = 0;
for (int i = 0; i < count; ++i)
{
   sum += v[i];
}
average = (float)sum / count;
}

// use average
// sum not in scope here

हालांकि मैं इसे एक विरोधी पैटर्न देखता हूं। आमतौर पर यदि आप ऐसा करने की आवश्यकता में खुद को पाते हैं तो सबसे अधिक संभावना है कि forयह स्वयं का कार्य होना चाहिए।


ठीक है अगर आपको लगता है कि यह अपने स्वयं के कार्य में होना चाहिए (मैं कई बार सोच सकता हूं कि जहां केवल बहुत कम से कम ओवरहेड जोड़ देगा लेकिन मैं वहां नहीं जा रहा हूं) आपके लिए एक काल्पनिक प्रश्न: अगर आपको ज़रूरत है तो क्या होगा एक स्विच मामले के लिए विशिष्ट स्थानीय गुंजाइश? निश्चित रूप से कई बार ऐसा होता है कि एक अतिरिक्त गुंजाइश (जो एक फ़ंक्शन भी करता है) को जोड़ना (ध्यान दें कि आपके उदाहरण के लिए, मुझे लगता है कि टी [एक अलग फ़ंक्शन एक बुरा विचार है) अनावश्यक है लेकिन अन्य समय ऐसा नहीं है, भले ही यह कितना सरल हो अन्य तरीके हैं।
प्रीफटन

2

यह ब्रेसिज़ द्वारा चिह्नित एक ब्लॉक स्कोप है{} । इसका उपयोग आमतौर पर स्वचालित भंडारण के क्षेत्र को चिह्नित करने के लिए किया जाता है । आपके मामले में यह कुछ भी करने के लिए प्रतीत नहीं होता है क्योंकि मानक C ++ में लूप का अपना दायरा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.