क्या यह सच है कि goto
विध्वंसक और चीजों को बुलाए बिना कोड के बिट्स में कूदता है?
जैसे
void f() {
int x = 0;
goto lol;
}
int main() {
f();
lol:
return 0;
}
x
लीक नहीं होगी?
क्या यह सच है कि goto
विध्वंसक और चीजों को बुलाए बिना कोड के बिट्स में कूदता है?
जैसे
void f() {
int x = 0;
goto lol;
}
int main() {
f();
lol:
return 0;
}
x
लीक नहीं होगी?
"Won't x be leaked"
मतलब है? प्रकार x
एक अंतर्निहित डेटा प्रकार है। आप एक बेहतर उदाहरण क्यों नहीं चुनते हैं?
goto
, तो वे सोचते हैं कि स्वचालित भंडारण अवधि चर भी किसी तरह "लीक" है। आप और मैं जानते हैं कि अन्यथा बिंदु के अलावा पूरी तरह से है।
int
रिसाव नहीं कर सकता , इसे लीक किया जा सकता है । उदाहरण के लिए: void f(void) { new int(5); }
लीक ए int
।
जवाबों:
चेतावनी: यह उत्तर केवल C ++ से संबंधित है ; सी में नियम काफी अलग हैं।
x
लीक नहीं होगी?
नहीं, बिल्कुल नहीं।
यह एक मिथक है goto
जो कुछ निम्न-स्तरीय निर्माण है जो आपको C ++ के अंतर्निर्मित स्कोपिंग तंत्र को ओवरराइड करने की अनुमति देता है। (यदि कुछ भी हो, तो longjmp
ऐसा हो सकता है।)
निम्नलिखित यांत्रिकी पर विचार करें जो आपको लेबल (जिसमें case
लेबल शामिल हैं) के साथ "बुरा काम" करने से रोकते हैं ।
आप कार्यों में नहीं कूद सकते:
void f() {
int x = 0;
goto lol;
}
int main() {
f();
lol:
return 0;
}
// error: label 'lol' used but not defined
[n3290: 6.1/1]:
[..] एक लेबल का कार्य वह कार्य है जिसमें यह प्रकट होता है। [..]
आप ऑब्जेक्ट आरंभीकरण पर नहीं जा सकते हैं:
int main() {
goto lol;
int x = 0;
lol:
return 0;
}
// error: jump to label ‘lol’
// error: from here
// error: crosses initialization of ‘int x’
यदि आप ऑब्जेक्ट आरंभीकरण पर वापस कूदते हैं , तो ऑब्जेक्ट का पिछला "उदाहरण" नष्ट हो जाता है :
struct T {
T() { cout << "*T"; }
~T() { cout << "~T"; }
};
int main() {
int x = 0;
lol:
T t;
if (x++ < 5)
goto lol;
}
// Output: *T~T*T~T*T~T*T~T*T~T*T~T
[n3290: 6.6/2]:
[..] एक लूप से बाहर, एक ब्लॉक से बाहर, या स्वचालित भंडारण अवधि के साथ एक प्रारंभिक चर के पीछे स्थानांतरण, इसमें स्वचालित भंडारण अवधि के साथ वस्तुओं का विनाश शामिल है, जो इस बिंदु पर गुंजाइश से दायरे में हैं, लेकिन इस बिंदु पर स्थानांतरित नहीं किया गया है । [..]
आप किसी वस्तु के दायरे में नहीं कूद सकते, भले ही यह स्पष्ट रूप से आरंभिक न हो:
int main() {
goto lol;
{
std::string x;
lol:
x = "";
}
}
// error: jump to label ‘lol’
// error: from here
// error: crosses initialization of ‘std::string x’
... कुछ विशेष प्रकार की वस्तु को छोड़कर , जो भाषा को संभाल सकती है क्योंकि उन्हें "जटिल" निर्माण की आवश्यकता नहीं है:
int main() {
goto lol;
{
int x;
lol:
x = 0;
}
}
// OK
[n3290: 6.7/3]:
एक ब्लॉक में स्थानांतरित करना संभव है, लेकिन इस तरह से नहीं कि प्रारंभिककरण के साथ घोषणाओं को बायपास करें। एक प्रोग्राम जो उस बिंदु से कूदता है जहां एक स्वचालित भंडारण अवधि वाला चर उस बिंदु के दायरे में नहीं होता है जहां वह दायरे में होता है, तब तक बीमार होता है जब तक कि चर स्केलर प्रकार, वर्ग प्रकार के साथ एक तुच्छ डिफ़ॉल्ट निर्माता और एक तुच्छ विध्वंसक नहीं होता है, इन प्रकारों में से एक का cv-योग्य संस्करण, या पूर्ववर्ती प्रकारों में से एक का एक सरणी और बिना इनिशलाइज़र के घोषित किया गया है। [..]
इसी तरह, स्वचालित भंडारण अवधि वाले ऑब्जेक्ट "लीक" नहीं होते हैं जब आप उनके दायरे से बाहर होते हैंgoto
:
struct T {
T() { cout << "*T"; }
~T() { cout << "~T"; }
};
int main() {
{
T t;
goto lol;
}
lol:
return 0;
}
// *T~T
[n3290: 6.6/2]:
एक दायरे (हालांकि पूरा) से बाहर निकलने पर, स्वचालित भंडारण अवधि (3.7.3) के साथ ऑब्जेक्ट जो उस दायरे में बनाए गए हैं, उनके निर्माण के रिवर्स ऑर्डर में नष्ट हो जाते हैं। [..]
उपरोक्त तंत्र यह सुनिश्चित करते हैं कि goto
आप भाषा को तोड़ने न दें।
बेशक, इसका मतलब यह नहीं है कि goto
किसी भी समस्या के लिए आपको "उपयोग" करना चाहिए , लेकिन इसका मतलब यह नहीं है कि यह "बुराई" के रूप में नहीं है क्योंकि आम मिथक लोगों को विश्वास करने के लिए प्रेरित करता है।