C ++ कोड को कैसे समाप्त करें


267

मैं चाहूंगा कि अगर कोई निश्चित शर्त पूरी हो जाए तो मैं अपना सी ++ कोड चलाना बंद कर दूंगा, लेकिन मुझे यकीन नहीं है कि ऐसा कैसे किया जाए। तो बस किसी भी बिंदु पर यदि कोई ifकथन सही है तो कोड को इस तरह समाप्त करें:

if (x==1)
{
    kill code;
}

98
उचित तर्क का प्रयोग करें। में main()उपयोग वापसी, कार्यों में एक उचित वापसी मान का उपयोग करें या एक उचित अपवाद फेंक देते हैं। उपयोग करें exit()!
- एसई बुराई है

6
@JonathanLeffler: जब NDEBUGपरिभाषित के साथ संकलित किया जाता है, assertतो संभावना नहीं सेशन बन जाएगा, इसलिए आपको इस पर निर्भर नहीं होना चाहिए क्योंकि यह कीड़े से अधिक है।
MvG

13
@jamesqf: एक returnसे main()पूरी तरह से तार्किक है। यह प्रोग्राम द्वारा रिपोर्ट किए गए एक्जिट कोड को ऑपरेटिंग सिस्टम पर सेट करता है, जो कई मामलों में उपयोगी हो सकता है (यदि आपका प्रोग्राम एक बड़ी प्रक्रिया के हिस्से के रूप में इस्तेमाल किया जा सकता है, उदाहरण के लिए)।
AAT

11
दिलचस्प बात यह है कि यह क्यू 5 साल पहले से एक का एक डुप्लिकेट है, जिसका स्वीकृत उत्तर काफी अलग है: stackoverflow.com/questions/1116493/how-to-quit-ac-program मुझे लगता है कि इस समुदाय को सीखने के लिए 5 साल लग गए: आँख बंद करके कॉलिंग std :: बाहर निकलना बुरा हो सकता है?
Brandin

5
प्रश्न क्यों exit()बुरा माना जाता है? - SO 25141737 और C ++ प्रोग्राम कैसे छोड़ें? - SO 1116493 अब इस एक के डुप्लिकेट के रूप में बंद हो गए हैं। उनमें से पहले में 'क्रैश-ओनली सॉफ्टवेयर' का संदर्भ है, जो देखने लायक हो सकता है, यदि केवल मजबूत सॉफ्टवेयर लिखने के तरीके के बारे में अपनी सोच को उत्तेजित करना है।
जोनाथन लेफ़लर

जवाबों:


431

कई तरीके हैं, लेकिन पहले आपको यह समझने की आवश्यकता है कि ऑब्जेक्ट क्लीनअप क्यों महत्वपूर्ण है, और इसलिए इसका कारण std::exitसी ++ प्रोग्रामर्स के बीच हाशिए पर है।

RAII और स्टैक अनवाइंडिंग

C ++ RAII नामक एक मुहावरे का उपयोग करता है , जिसका साधारण अर्थ है कि वस्तुओं को निर्माणकर्ता में आरंभीकरण करना चाहिए और विध्वंसक में सफाई करना चाहिए। उदाहरण के लिए, std::ofstreamक्लास निर्माणकर्ता के दौरान फ़ाइल खोल सकता है, फिर उपयोगकर्ता उस पर आउटपुट ऑपरेशन करता है, और अंत में अपने जीवन चक्र के अंत में, आमतौर पर इसके दायरे से निर्धारित होता है, विध्वंसक को कहा जाता है कि अनिवार्य रूप से फ़ाइल को बंद कर देता है और फ्लश करता है डिस्क में कोई भी लिखित सामग्री।

यदि आप विध्वंसक को फ़ाइल को फ्लश और बंद करने के लिए नहीं आते हैं तो क्या होगा? कौन जाने! लेकिन संभवत: यह वह सभी डेटा नहीं लिखेगा जो इसे फाइल में लिखना चाहिए था।

उदाहरण के लिए इस कोड पर विचार करें

#include <fstream>
#include <exception>
#include <memory>

void inner_mad()
{
    throw std::exception();
}

void mad()
{
    auto ptr = std::make_unique<int>();
    inner_mad();
}

int main()
{
    std::ofstream os("file.txt");
    os << "Content!!!";

    int possibility = /* either 1, 2, 3 or 4 */;

    if(possibility == 1)
        return 0;
    else if(possibility == 2)
        throw std::exception();
    else if(possibility == 3)
        mad();
    else if(possibility == 4)
        exit(0);
}

प्रत्येक संभावना में क्या होता है:

  • संभावना 1: रिटर्न अनिवार्य रूप से वर्तमान फ़ंक्शन स्कोप को छोड़ देता है, इसलिए यह osइस तरह से अपने डिस्ट्रक्टर को कॉल करने और डिस्क को फाइल को फ्लश और बंद करके उचित सफाई करने के जीवन चक्र के अंत के बारे में जानता है ।
  • संभावना 2: अपवाद को फेंकना वर्तमान दायरे में वस्तुओं के जीवन चक्र का भी ध्यान रखता है, इस प्रकार उचित सफाई ...
  • संभावना 3: यहां स्टैक अनइंडिंग कार्रवाई में प्रवेश करती है! भले ही अपवाद को फेंक दिया गया हो inner_mad, फिर भी अनइन्डर जाएगा, हालांकि ढेर madऔर mainउचित सफाई करने के लिए, सभी वस्तुओं को सही तरीके से नष्ट किया जा रहा है, जिसमें शामिल हैं ptrऔर os
  • संभावना 4: खैर, यहाँ? exitएक C फ़ंक्शन है और यह C ++ मुहावरों के बारे में पता नहीं है और न ही संगत है। यह आपकी वस्तुओं पर सफाई का प्रदर्शन नहीं करता है , जिसमें osबहुत ही गुंजाइश भी शामिल है। तो आपकी फ़ाइल ठीक से बंद नहीं होगी और इस कारण से सामग्री कभी भी उसमें नहीं लिखी जा सकती है!
  • अन्य संभावनाएँ: यह सिर्फ एक चीरा लगाकर मुख्य संभावना छोड़ देगा, return 0इस प्रकार संभावना 1, अर्थात उचित सफाई के समान प्रभाव होगा।

लेकिन जो मैंने अभी आपको (मुख्यतः 2 और 3 की संभावनाएँ) बताई हैं, उनके बारे में कुछ निश्चित न करें; पढ़ना जारी रखें और हमें पता चलेगा कि एक उचित अपवाद आधारित सफाई कैसे करें।

अंत करने के लिए संभव तरीके

मुख्य से लौटें!

जब भी संभव हो आपको ऐसा करना चाहिए; हमेशा मुख्य से एक उचित निकास स्थिति को वापस करके अपने कार्यक्रम से वापस आना पसंद करें।

आपके प्रोग्राम का कॉलर, और संभवतः ऑपरेटिंग सिस्टम, यह जानना चाह सकता है कि आपका प्रोग्राम क्या करने वाला था, सफलतापूर्वक किया गया था या नहीं। इसी कारण से आपको या तो शून्य पर लौटना चाहिए या EXIT_SUCCESSयह संकेत देने के लिए कि कार्यक्रम सफलतापूर्वक समाप्त हो गया है और EXIT_FAILUREकार्यक्रम को असफल रूप से समाप्त करने का संकेत देने के लिए, वापसी मूल्य का कोई अन्य रूप कार्यान्वयन-परिभाषित है ( .518.5 / 8 )।

हालाँकि आप कॉल स्टैक में बहुत गहरे हो सकते हैं, और यह सब वापस आना दर्दनाक हो सकता है ...

[मत करो] एक अपवाद न फेंकें

किसी अपवाद को फेंकना किसी भी पिछले दायरे में हर वस्तु के विध्वंसक को कॉल करके स्टैक अनइंडिंग का उपयोग करके उचित ऑब्जेक्ट क्लीनअप करेगा।

लेकिन यहाँ पकड़ है ! यह कार्यान्वित-परिभाषित है कि क्या स्टैक अनइंडिंग किया जाता है जब फेंक दिया गया अपवाद नहीं पकड़ा जाता है (कैच (...) क्लॉज द्वारा) या यहां तक ​​कि अगर आपके पास noexceptकॉल स्टैक के बीच में कोई फ़ंक्शन है। इस में कहा गया है §15.5.1 [except.terminate] :

  1. कुछ स्थितियों में अपवाद हैंडलिंग को कम सूक्ष्म त्रुटि हैंडलिंग तकनीकों के लिए छोड़ दिया जाना चाहिए। [नोट: ये स्थितियाँ हैं:

    [...]

    - जब अपवाद हैंडलिंग तंत्र एक फेंके गए अपवाद (15.3) के लिए हैंडलर नहीं ढूंढ सकता है, या जब हैंडलर (15.3) की खोज किसी फ़ंक्शन के सबसे बाहरी ब्लॉक का सामना करती है,noexcept जो कि एक अनिर्दिष्टता (अपवाद) (15.4) की अनुमति नहीं देता है, या [...]

    [...]

  2. ऐसे मामलों में, std :: terminate () कहा जाता है (18.8.3)। ऐसी स्थिति में जहां कोई मिलान करने वाला हैंडलर नहीं मिलता है, यह कार्यान्वयन-परिभाषित है कि क्या स्टैक :: टर्मिनेट () कहा जाता है इससे पहले कि स्टैक निराधार है या नहीं [...]

इसलिए हमें इसे पकड़ना होगा!

एक अपवाद को फेंक दो और इसे मुख्य रूप से पकड़ लो!

चूंकि बिना किसी अपवाद के स्टैक अनइंडिंग नहीं किया जा सकता है (और परिणामस्वरूप उचित सफाई नहीं करेगा) , हमें मुख्य में अपवाद को पकड़ना चाहिए और फिर एक निकास स्थिति ( EXIT_SUCCESSया EXIT_FAILURE) वापस करना चाहिए ।

तो संभवतः एक अच्छा सेटअप होगा:

int main()
{
    /* ... */
    try
    {
        // Insert code that will return by throwing a exception.
    }
    catch(const std::exception&)  // Consider using a custom exception type for intentional
    {                             // throws. A good idea might be a `return_exception`.
        return EXIT_FAILURE;
    }
    /* ... */
}

[मत करो] एसटीडी :: बाहर निकलें

यह किसी भी प्रकार के स्टैक अनइंडिंग का प्रदर्शन नहीं करता है, और स्टैक पर कोई भी जीवित वस्तु अपने संबंधित डिस्ट्रक्टर को सफाई करने के लिए नहीं बुलाएगी।

यह §3.6.1 / 4 में लागू किया गया है [basic.start.init] :

वर्तमान ब्लॉक को छोड़कर कार्यक्रम को समाप्त करना (जैसे, फ़ंक्शन std :: exit (int) (18.5) कॉल करके स्वचालित भंडारण अवधि (12.4) के साथ किसी भी ऑब्जेक्ट को नष्ट नहीं करता है । यदि std :: exit को किसी वस्तु के विनाश के दौरान स्थैतिक या थ्रेड स्टोरेज अवधि के दौरान प्रोग्राम को समाप्त करने के लिए कहा जाता है, तो प्रोग्राम में अपरिभाषित व्यवहार होता है।

अब इसके बारे में सोचो, आप ऐसा क्यों करेंगे? आपने कितनी वस्तुओं को नुकसान पहुँचाया है?

अन्य [के रूप में बुरा] विकल्प

एक कार्यक्रम (दुर्घटनाग्रस्त होने के अलावा) को समाप्त करने के अन्य तरीके हैं , लेकिन वे अनुशंसित नहीं हैं। सिर्फ स्पष्टीकरण के लिए वे यहां प्रस्तुत होने जा रहे हैं। ध्यान दें कि सामान्य प्रोग्राम समाप्ति का मतलब स्टैक अनइंडिंग नहीं है, लेकिन ऑपरेटिंग सिस्टम के लिए एक ठीक स्थिति है।

  • std::_Exit एक सामान्य कार्यक्रम समाप्ति का कारण बनता है, और यह बात है।
  • std::quick_exitएक सामान्य कार्यक्रम समाप्ति का कारण बनता है और std::at_quick_exitहैंडलर को बुलाता है, कोई अन्य सफाई नहीं की जाती है।
  • std::exitएक सामान्य कार्यक्रम समाप्ति का कारण बनता है और फिर std::atexitहैंडलर को बुलाता है। अन्य प्रकार के क्लीनअप का प्रदर्शन किया जाता है जैसे स्थैतिक वस्तुओं को विध्वंसक कहना।
  • std::abortएक असामान्य कार्यक्रम समाप्ति का कारण बनता है, कोई सफाई नहीं की जाती है। यह कहा जाना चाहिए कि क्या कार्यक्रम वास्तव में, वास्तव में अप्रत्याशित तरीके से समाप्त हो गया है। यह असामान्य समाप्ति के बारे में ओएस के सिवा कुछ नहीं करेगा। कुछ सिस्टम इस मामले में एक कोर डंप करते हैं।
  • std::terminateकॉल std::terminate_handlerजो कहता है std::abortडिफ़ॉल्ट रूप से।

25
यह काफी जानकारीपूर्ण है: विशेष रूप से मुझे कभी भी यह एहसास नहीं हुआ कि एक अपवाद को फेंकना जो कहीं भी संभाला नहीं गया है (उदाहरण के लिए: कुछ newफेंकता है std::bad_allocऔर आपका कार्यक्रम उस अपवाद को पकड़ने के लिए भूल गया) समाप्त होने से पहले स्टैक को ठीक से खोलना नहीं होगा । यह मुझे मूर्खतापूर्ण लगता है: कॉल को अनिवार्य रूप mainसे एक तुच्छ try{- }catch(...){}ब्लॉक में लपेटना आसान होता, जो सुनिश्चित करता कि स्टैक अनइंडिंग ठीक से ऐसे मामलों में किया जाता है, बिना किसी लागत के (जिससे मेरा मतलब है: इस का उपयोग करने वाले प्रोग्राम नहीं का भुगतान नहीं करेंगे दंड)। क्या ऐसा कोई विशेष कारण नहीं है?
मार्क वैन लीउवेन

12
@MarcvanLeeuwen एक संभावित कारण डिबगिंग है: आप जैसे ही डिबगर में तोड़ना चाहते हैं, जैसे ही कोई अनहोनी अपवाद फेंक दिया जाता है। स्टैक को खोलना और सफाई करना उस संदर्भ को मिटा देगा जो दुर्घटना का कारण बना जिसे आप डिबग करना चाहते हैं। यदि कोई डिबगर मौजूद नहीं है तो कोर को डंप करना बेहतर हो सकता है ताकि पोस्टमॉर्टम विश्लेषण किया जा सके।
ह्यू एलेन

11
कभी-कभी मेरा ब्राउज़र खराब हो जाता है (मैं फ्लैश को दोष देता हूं) और कई गीगाबाइट रैम का उपभोग करता हूं और हार्ड ड्राइव पर मेरा ओएस डंप करता है। जब मैं ब्राउज़र को बंद कर देता हूं तो यह उचित स्टैक अनइंडिंग करता है, जिसका अर्थ है कि उन सभी गीगाबाइट रैम को हार्ड-ड्राइव से पढ़ा जाता है और मेमोरी में कॉपी किया जाता है, जिसे केवल एक या दो मिनट के लिए छोड़ा जाता है। मेरी इच्छा है कि वे std::abortइसके बजाय उपयोग करते थे इसलिए ओएस एक मिनट के लिए स्वैप किए बिना सभी मेमोरी, सॉकेट्स और फ़ाइल डिस्क्रिप्टर जारी कर सकता है।
nwp

2
@ एनडब्ल्यूपी, मैं भावना को समझता हूं। लेकिन तुरन्त मारने से भ्रष्ट फाइलें, मेरे सबसे हाल के टैब आदि को नहीं बचा
पातीं

2
@PaulDraper मैं निश्चित रूप से इसे सहन करने योग्य नहीं मानूंगा यदि कोई ब्राउज़र एक बिजली की हानि से पहले मेरे द्वारा खोले गए टैब को पुनर्स्थापित नहीं कर सकता है। बेशक अगर मैंने सिर्फ एक टैब खोला था, और इसे बचाने के लिए अभी समय नहीं था, तो यह खो जाएगा। लेकिन इसके अलावा, मैं कहता हूं कि इसे खोने का कोई बहाना नहीं है।
कैस्परड

61

जैसा कि मार्टिन यॉर्क ने उल्लेख किया है, निकास आवश्यक सफाई नहीं करता है जैसे रिटर्न करता है।

निकास के स्थान पर रिटर्न का उपयोग करना हमेशा बेहतर होता है। यदि आप मुख्य में नहीं हैं, तो आप कार्यक्रम से बाहर निकलना चाहते हैं, तो पहले मुख्य पर लौटें।

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

int main()
{
    ofstream os("out.txt");
    os << "Hello, Can you see me!\n";
    return(0);
    //exit(0);
}

इतना ही नहीं, एक प्रोग्राम में कई एग्जिट पॉइंट होने से डीबगिंग कठिन हो जाएगी। निकास का उपयोग तभी करें जब इसे उचित ठहराया जा सके।


2
थोड़े बड़े कार्यक्रम में इस व्यवहार को प्राप्त करने के लिए आप क्या सलाह देते हैं? यदि कोड में कोई त्रुटि स्थिति शुरू हो जाती है जो प्रोग्राम से बाहर निकलना चाहिए तो आप हमेशा मुख्य सफाई से कैसे लौटेंगे?
Janusz

5
@ जानुस, उस स्थिति में, आप अपवादों का उपयोग / फेंक सकते हैं, यदि पूर्व-परिभाषित मूल्य नहीं लौटाते हैं, तो फ़ंक्शन से वापसी मान है, उदाहरण के लिए वापसी 0 जब सफल होता है, तो विफलता के मामले में 1, लेकिन निष्पादन जारी रखें , -1, विफलता के मामले में और कार्यक्रम से बाहर निकलें। फ़ंक्शन से वापसी मान के आधार पर, यदि यह विफलता है, तो बस किसी भी अधिक साफ-सफाई की गतिविधियों को करने के बाद मुख्य से वापस लौटें। अंत में, विवेकपूर्ण तरीके से निकास का उपयोग करें, मेरा मतलब इससे बचने का नहीं है।
नरेंद्र एन

1
@ नरेंद्रन, "आवश्यक सफाई" अस्पष्ट है - ओएस ध्यान रखेगा (विंडोज / लिनक्स) कि स्मृति और फ़ाइल हैंडल ठीक से जारी किए गए हैं। "अनुपलब्ध" फ़ाइल आउटपुट के लिए: यदि आप जोर देते हैं कि यह एक वास्तविक समस्या हो सकती है, तो देखें stackoverflow.com/questions/14105650/how-does-stdflush-work यदि आपके पास कोई त्रुटि स्थिति है, तो उचित लॉगिंग आपको बताती है कि आपका प्रोग्राम एक अपरिभाषित स्थिति पर पहुंच गया और आप अपने लॉगिंग बिंदु से ठीक पहले एक ब्रेकपॉइंट सेट कर सकते हैं। यह कैसे डिबगिंग को कठिन बनाता है?
मार्कस

2
ध्यान दें कि यह उत्तर इस प्रश्न से मिला दिया गया था कि C ++ प्रोग्राम कैसे छोड़ें? - तो 1,116,493 । यह प्रश्न पूछे जाने से लगभग 6 साल पहले लिखा गया था।
जोनाथन लेफ़लर

return (EXIT_SUCCESS);इसके बजाय आधुनिक C ++ उपयोग के लिए return(0)
जोनास स्टीन

39

std::exitफ़ंक्शन को कॉल करें ।   


2
जब आप उस फ़ंक्शन को कॉल करते हैं, तो किस ऑब्जेक्ट के विध्वंसक को कहा जाता है?
रोब कैनेडी

37
बाहर निकलना () वापस नहीं आता। तो कोई स्टैक अनडिंडिंग नहीं हो सकता है। वैश्विक वस्तुएं भी नष्ट नहीं होतीं। लेकिन एटैक्सिट () के साथ पंजीकृत कार्यों को कहा जाएगा।
मार्टिन

16
exit()जब आपका लाइब्रेरी कोड मेरी होस्ट प्रक्रिया के अंदर चल रहा हो, तो कॉल न करें - बाद वाला कहीं नहीं के बीच से बाहर निकल जाएगा।
शार्प्यूट

5
ध्यान दें कि यह उत्तर इस प्रश्न से मिला दिया गया था कि C ++ प्रोग्राम कैसे छोड़ें? - तो 1,116,493 । यह प्रश्न पूछे जाने से लगभग 6 साल पहले लिखा गया था।
जोनाथन लेफ़लर

23

लोग "कॉल एक्जिट (रिटर्न कोड)" कह रहे हैं, लेकिन यह खराब रूप है। छोटे कार्यक्रमों में यह ठीक है, लेकिन इसके साथ कई मुद्दे हैं:

  1. आप कार्यक्रम से कई निकास बिंदुओं को समाप्त करेंगे
  2. यह कोड को और अधिक जटिल बनाता है (जैसे गोटो का उपयोग करके)
  3. यह रनटाइम पर आवंटित मेमोरी को जारी नहीं कर सकता है

वास्तव में, समस्या से बाहर निकलने का एकमात्र समय main.cpp में इस लाइन के साथ है:

return 0;

यदि आप त्रुटियों को संभालने के लिए निकास () का उपयोग कर रहे हैं, तो आपको अपवादों के बारे में सीखना चाहिए (और अपवादों को छोड़कर), अधिक सुंदर और सुरक्षित विधि के रूप में।


9
बहु-थ्रेडेड वातावरण में, एक अलग थ्रेड में फेंके गए अपवाद को हालांकि मुख्य रूप से नहीं संभाला जाएगा () - अधीनस्थ थ्रेड के समाप्त होने से पहले कुछ मैनुअल क्रॉस-थ्रेड संचार की आवश्यकता होती है।
स्टीव गिलहम

3
1. और 2. प्रोग्रामर पर निर्भर हैं, उचित लॉगिंग के साथ यह कोई समस्या नहीं है क्योंकि हमेशा के लिए छूटना बंद हो जाता है। 3 के रूप में: यह सिर्फ सादा गलत है, ओएस मेमोरी को मुक्त कर देगा - शायद एम्बेडेड डिवाइस / रियलटाइम को छोड़कर, लेकिन यदि आप ऐसा कर रहे हैं, तो आप शायद अपना सामान जानते हैं।
मार्कस

1
ध्यान दें कि यह उत्तर इस प्रश्न से मिला दिया गया था कि C ++ प्रोग्राम कैसे छोड़ें? - तो 1,116,493 । यह प्रश्न पूछे जाने से लगभग 6 साल पहले लिखा गया था।
जोनाथन लेफ़लर

1
यदि कोई त्रुटि हुई, तो आपको वापस नहीं लौटना चाहिए। आपको 1 वापस करना चाहिए (या संभवतः कुछ अन्य मूल्य, लेकिन 1 हमेशा एक सुरक्षित विकल्प है)।
केफ शेक्टर

14

return 0;रखो कि तुम जहाँ भी चाहते हो int main()और कार्यक्रम तुरंत बंद हो जाएगा।


रात में, @ इवान-कारसेलेक, और बाकी सभी, मैं यह भी जोड़ूंगा कि यह एसओ प्रश्न # 36707 इस बात की चर्चा करता है कि क्या वापसी का बयान सिर्फ एक दिनचर्या में कहीं भी होना चाहिए। यह एक समाधान है; हालांकि, विशिष्ट स्थिति के आधार पर, मैं यह नहीं कहूंगा कि यह सबसे अच्छा समाधान है।
लोकलहोस्ट

1
ओपी ने कहा कि इस बारे में कुछ भी नहीं है, इसलिए मुझे लगता है कि यह माना जाता है कि फ़ंक्शन के अंदर कोड होना चाहिए main
मार्क वैन लीउवेन

किसी भी परिस्थिति में @localhost एक रिटर्न स्टेटमेंट हर स्थिति में पूरी तरह से वैकल्पिक है। हालाँकि, int main()अलग है। कार्यक्रम का उपयोग int main()शुरू और अंत करने के लिए होता है। इसे करने का कोई और तरीका नहीं है। कार्यक्रम तब तक चलेगा जब तक आप सही या गलत नहीं लौटते। लगभग सभी समय जब आप 1 या सही लौटाएंगे, यह इंगित करने के लिए कि प्रोग्राम सही ढंग से बंद हो गया है (उदाहरण: गलत का उपयोग कर सकता है यदि आप मेमोरी या जो भी कारण मुक्त नहीं कर सके।) प्रोग्राम को स्वयं समाप्त होने देना हमेशा एक बुरा विचार है, उदाहरण:int main() { int x = 2; int foo = x*5; std::cout << "blah"; }
इवान कार्सलेक

@EvanCarslake अंडरस्टूड, अगर आपने एक टिप्पणी देखी जो मैंने इस प्रश्न के लिए कहीं और पोस्ट की है, तो मैं इसके बारे में परिचित हूं int main; हालाँकि, यह हमेशा एक अच्छा विचार नहीं होता है जिसमें मुख्य दिनचर्या में कई रिटर्न स्टेटमेंट होते हैं। एक संभावित चेतावनी कोड पठनीयता में सुधार करना है; हालाँकि, बूलियन ध्वज की तरह कुछ का उपयोग करना जो कोड के कुछ कोड सेक्शन को रोकने के लिए राज्य को बदल देता है। व्यक्तिगत रूप से, मुझे लगता है कि एक सामान्य रिटर्न स्टेटमेंट अधिकांश अनुप्रयोगों को अधिक पठनीय बनाता है। अंत में, मेमोरी क्लीनअप और I / O ऑब्जेक्ट्स को निकास से पहले ठीक से बंद करने के बारे में प्रश्न।
लोकलहोस्ट

2
@EvanCarslake आप एक सही समाप्ति का संकेत trueदेने के mainलिए वापस नहीं आते हैं । सामान्य समाप्ति को इंगित करने के लिए EXIT_SUCCESSआपको शून्य या (या, यदि आप चाहें false, जिसे अंतर्निहित रूप से शून्य में बदल दिया जाएगा) वापस करना होगा। विफलता को इंगित करने के लिए आप वापस लौट सकते हैं EXIT_FAILURE। किसी भी अन्य कोड का अर्थ कार्यान्वयन-परिभाषित है (POSIX सिस्टम पर इसका मतलब वास्तविक त्रुटि कोड होगा)।
रुस्लान

11

कार्यक्रम समाप्त हो जाएगा जब निष्पादन प्रवाह मुख्य फ़ंक्शन के अंत तक पहुंचता है।

तब से पहले इसे समाप्त करने के लिए, आप एग्जिट (इंट स्टेटस) फ़ंक्शन का उपयोग कर सकते हैं, जहां स्थिति जो भी प्रोग्राम शुरू किया गया है, उसका एक मूल्य है। 0 आमतौर पर एक गैर-त्रुटि स्थिति को इंगित करता है


2
ध्यान दें कि यह उत्तर इस प्रश्न से मिला दिया गया था कि C ++ प्रोग्राम कैसे छोड़ें? - तो 1,116,493 । यह प्रश्न पूछे जाने से लगभग 6 साल पहले लिखा गया था।
जोनाथन लेफ्लर

11

या तो अपने से एक मान लौटाएँ mainया exitफ़ंक्शन का उपयोग करें । दोनों एक इंट लेते हैं। यह वास्तव में मायने नहीं रखता कि आप तब तक किस मूल्य पर लौटते हैं जब तक कि आपके पास वापसी मूल्य के लिए देखने की बाहरी प्रक्रिया न हो।


3
ध्यान दें कि यह उत्तर इस प्रश्न से मिला दिया गया था कि C ++ प्रोग्राम कैसे छोड़ें? - तो 1,116,493 । यह प्रश्न पूछे जाने से लगभग 6 साल पहले लिखा गया था।
जोनाथन लेफ्लर

11

यदि आपके पास कोड में कहीं गहरी त्रुटि है, तो या तो एक अपवाद फेंक दें या त्रुटि कोड सेट करें। त्रुटि कोड सेट करने के बजाय अपवाद फेंकना हमेशा बेहतर होता है।


2
ध्यान दें कि यह उत्तर इस प्रश्न से मिला दिया गया था कि C ++ प्रोग्राम कैसे छोड़ें? - तो 1,116,493 । यह प्रश्न पूछे जाने से लगभग 6 साल पहले लिखा गया था।
जोनाथन लेफ्लर

9

आम तौर पर आप exit()एक उपयुक्त निकास स्थिति के साथ विधि का उपयोग करेंगे ।

शून्य का मतलब होगा एक सफल रन। एक गैर-शून्य स्थिति इंगित करती है कि किसी प्रकार की समस्या हुई है। यह एक्ज़िट कोड मूल प्रक्रियाओं (जैसे शेल स्क्रिप्ट) द्वारा उपयोग किया जाता है ताकि यह निर्धारित किया जा सके कि कोई प्रक्रिया सफलतापूर्वक चली है।


1
MAY से बाहर निकलने का मतलब है कि आपको डिज़ाइन की समस्या है। यदि कोई प्रोग्राम सही ढंग से bheaves करता है तो उसे मुख्य होने पर ही समाप्त कर देना चाहिए return 0;। मुझे लगता exit()है कि ऐसा है assert(false);और इसलिए इसका उपयोग विकास में केवल शुरुआती समस्याओं को पकड़ने के लिए किया जाना चाहिए।
कॉफ़ीड्यूवेलर

2
ध्यान दें कि यह उत्तर इस प्रश्न से मिला दिया गया था कि C ++ प्रोग्राम कैसे छोड़ें? - तो 1,116,493 । यह प्रश्न पूछे जाने से लगभग 6 साल पहले लिखा गया था।
जोनाथन लेफ्लर

7

कॉलिंग एग्जिट (त्रुटि_कोड) से परे - जो एटैक्सिट हैंडलर्स को कॉल करता है, लेकिन आरएआईआई डिस्ट्रक्टर्स को नहीं, आदि - अधिक से अधिक मैं अपवादों का उपयोग कर रहा हूं।

अधिक से अधिक मेरा मुख्य कार्यक्रम जैसा दिखता है

int main(int argc, char** argv) 
{
    try {
        exit( secondary_main(argc, argv );
    }
    catch(...) {
        // optionally, print something like "unexpected or unknown exception caught by main"
        exit(1);
    }
}

जहाँ गौण_मैं, जिसमें मूल रूप से डाला गया सारा सामान - यानी मूल मुख्य का नाम बदलकर गौण_माँ रखा जाता है, और ऊपर मुख्य स्टब जोड़ा जाता है। यह सिर्फ एक अच्छा हिस्सा है, ताकि ट्रे और मुख्य में पकड़ के बीच बहुत अधिक कोड न हो।

यदि आप चाहते हैं, तो अन्य अपवाद प्रकारों को पकड़ें।
मैं काफी स्ट्रिंग त्रुटि प्रकारों को पकड़ना पसंद करता हूं, जैसे std :: string या char *, और मुख्य रूप से पकड़ने वाले हैंडलर में प्रिंट करना।

कम से कम इस तरह के अपवादों का उपयोग करने से आरएआईआई विध्वंसक को बुलाया जा सकता है, ताकि वे सफाई कर सकें। जो सुखद और उपयोगी हो सकता है।

कुल मिलाकर, C एरर हैंडलिंग - एग्जिट और सिग्नल - और C ++ एरर हैंडलिंग - एक्सेप्ट / कैच / थ्रो अपवाद - असंगत रूप से एक साथ खेलते हैं।

फिर, जहाँ आप एक त्रुटि का पता लगाते हैं

throw "error message"

या कुछ और विशिष्ट अपवाद प्रकार।


वैसे: मैं अच्छी तरह से जानता हूं कि स्ट्रिंग जैसे डेटा प्रकार का उपयोग करना, जिसमें गतिशील मेमोरी आवंटन शामिल हो सकता है, अपवाद के लिए या उसके आसपास अपवाद हैंडलर में एक अच्छा विचार नहीं है जो स्मृति से बाहर चलने से संबंधित हो सकता है। सी-स्टाइल स्ट्रिंग स्थिरांक एक समस्या नहीं हैं।
क्रेजी ग्लीव

1
exitआपके कार्यक्रम में बुलाने का कोई मतलब नहीं है । जब से तुम में हो main, तुम बस कर सकते हो return exitCode;
रुस्लान

-1

यदि आपका स्टेटमेंट लूप में है तो आप उपयोग कर सकते हैं

 break; 

यदि आप कुछ कोड से बचना चाहते हैं और लूप जारी रखना चाहते हैं:

जारी रखें;

यदि आपका बयान लूप में नहीं है तो आप इसका उपयोग कर सकते हैं:

 return 0;

Or 




  exit();

-2

यार ... exit()फ़ंक्शन को stdlib.h के तहत परिभाषित किया गया है

इसलिए आपको एक प्रीप्रोसेसर जोड़ना होगा।

include stdlib.hहेडर सेक्शन में रखें

फिर exit();आप जहाँ चाहें उपयोग करें लेकिन बाहर निकलने के कोष्ठक में एक अंतराल संख्या डालना याद रखें।

उदाहरण के लिए:

exit(0);

-2

अगर मैं जिस स्थिति का परीक्षण कर रहा हूं, वह वास्तव में बुरी खबर है, तो मैं यह करता हूं:

*(int*) NULL= 0;

यह मुझे एक अच्छा coredump देता है जहां से मैं स्थिति की जांच कर सकता हूं।


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

-2

एक शर्त को तोड़ने के लिए रिटर्न (0) का उपयोग करें;

तो, आपके मामले में यह होगा:

    if(x==1)
    {
        return 0;
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.