C में रिटर्न n और एक्जिट (n) में कोई अंतर है?


9

क्या return n( mainफंक्शन में) और exit(n)C में कोई अंतर है? क्या इसे C या POSIX मानकों द्वारा परिभाषित किया गया है या यह OS या कंपाइलर पर निर्भर करता है?

जवाबों:


5

ज्यादातर मामलों में, कोई अंतर नहीं है, लेकिन यहां एक सी प्रोग्राम है जो इस बात पर निर्भर करता है कि यह उपयोग करता है return 0;या exit(0);:

#include <stdio.h>
#include <stdlib.h>

static char *message;

void cleanup(void) {
    printf("message = \"%s\"\n", message);
}

int main(void) {
    char local_message[] = "hello, world";
    message = local_message;
    atexit(cleanup);
#ifdef USE_EXIT
    puts("exit(0);");
    exit(0);
#else
    puts("return 0;");
    return 0;
#endif
}

की वजह से atexit()कॉल, या तो exit(0);या return 0;कारणों cleanupसमारोह लागू किया जा करने के लिए। अंतर यह है कि यदि प्रोग्राम कॉल करता है exit(0);, तो सफाई तब होती है जबकि "कॉल" main()अभी भी सक्रिय है, इसलिए local_messageऑब्जेक्ट अभी भी मौजूद है। return 0;हालाँकि, निष्पादन को तुरंत रद्द कर दिया जाता है main()और फिरcleanup() समारोह को आमंत्रित करता है। चूँकि cleanup()संदर्भित करता है (वैश्विक messageसूचक के माध्यम से ) एक वस्तु जो स्थानीय स्तर पर आवंटित की जाती है main, और वह वस्तु अब मौजूद नहीं है, व्यवहार अपरिभाषित है।

यहाँ मैं अपने सिस्टम पर देख रहा हूँ:

$ gcc -DUSE_EXIT c.c -o c && ./c
exit(0);
message = "hello, world"
$ gcc c.c -o c && ./c
return 0;
message = ""
$ 

कार्यक्रम को चलाने के बिना -DUSE_EXITकुछ भी नहीं किया जा सकता है, जिसमें दुर्घटनाग्रस्त होने या छपाई शामिल है "hello, world"(यदि उपयोग की जाने वाली मेमोरी local_messageको बंद नहीं किया जाना है)।

व्यवहार में, हालांकि, यह अंतर केवल यह दिखाता है कि स्थानीय रूप से परिभाषित वस्तुएं main()बाहर की ओर main()इशारा करते हुए दिखाई देती हैं। यह बहुतायत से हो सकता है argv। (मेरे सिस्टम पर प्रयोग से पता चलता है कि वस्तुओं द्वारा argvऔर उसके द्वारा *argvलौटने के बाद भी मौजूद होने का संकेत मिलता है main(), लेकिन आपको उस पर निर्भर नहीं होना चाहिए।)


16
  • सी के लिए
    द स्टैंडर्ड का कहना है कि शुरुआती कॉल से लेकर मेन तक का रिटर्न कॉलिंग एग्जिट के बराबर है। हालाँकि, मुख्य से वापसी की उम्मीद नहीं की जा सकती अगर सफाई के दौरान स्थानीय से मुख्य डेटा की आवश्यकता हो।

  • C ++ के लिए

जब प्रोग्राम से बाहर निकलने के लिए एग्जिट (0) का उपयोग किया जाता है, तो स्थानीय रूप से स्कॉप्ड नॉन-स्टैटिक ऑब्जेक्ट के लिए डिस्ट्रक्टर्स को नहीं बुलाया जाता है। लेकिन डिस्ट्रक्टर्स को कहा जाता है यदि रिटर्न 0 का उपयोग किया जाता है।

प्रोग्राम 1 - - बाहर निकलने के लिए (0) का उपयोग करता है

#include<iostream>
#include<stdio.h>
#include<stdlib.h>

using namespace std;

class Test {
public:
  Test() {
    printf("Inside Test's Constructor\n");
  }

  ~Test(){
    printf("Inside Test's Destructor");
    getchar();
  }
};

int main() {
  Test t1;

  // using exit(0) to exit from main
  exit(0);
}

आउटपुट: इनसाइड टेस्ट के कंस्ट्रक्टर

प्रोग्राम 2 - बाहर निकलने के लिए 0 रिटर्न का उपयोग करता है

#include<iostream>
#include<stdio.h>
#include<stdlib.h>

using namespace std;

class Test {
public:
  Test() {
    printf("Inside Test's Constructor\n");
  }

  ~Test(){
    printf("Inside Test's Destructor");
  }
};

int main() {
  Test t1;

   // using return 0 to exit from main
  return 0;
}

आउटपुट: इनसाइड टेस्ट के कंस्ट्रक्टर
इनसाइड टेस्ट के डिस्ट्रक्टर

डिस्ट्रक्टर्स को कॉल करना कभी-कभी महत्वपूर्ण होता है, उदाहरण के लिए, यदि डिस्ट्रॉक्टर के पास फाइल बंद करने जैसे संसाधनों को जारी करने के लिए कोड होता है।

ध्यान दें कि अगर हम बाहर निकलें () कहते हैं तो भी स्थैतिक वस्तुओं को साफ किया जाएगा। उदाहरण के लिए, निम्नलिखित प्रोग्राम देखें।

#include<iostream>
#include<stdio.h>
#include<stdlib.h>

using namespace std;

class Test {
public:
  Test() {
    printf("Inside Test's Constructor\n");
  }

  ~Test(){
    printf("Inside Test's Destructor");
    getchar();
  }
};

int main() {
  static Test t1;  // Note that t1 is static

  exit(0);
}

आउटपुट: इनसाइड टेस्ट के कंस्ट्रक्टर
इनसाइड टेस्ट के डिस्ट्रक्टर


जब आप बाहर निकल रहे हों, तो फाइलों को बंद करना वास्तव में एक महत्वपूर्ण विध्वंसक का अच्छा उदाहरण नहीं है, क्योंकि प्रोग्राम से बाहर निकलने पर फ़ाइलें बंद हो जाएंगी।
विंस्टन एवर्ट

1
@WinstonEwert: यह सच है, लेकिन एप्लिकेशन-स्तरीय बफ़र्स मौजूद हो सकते हैं जिन्हें अभी भी फ्लश करने की आवश्यकता है।
फिलिप

1
प्रश्न में कहीं भी C ++ का उल्लेख नहीं है ...
tdammers

मुझे पता है कि न तो भाषा मुझे माफ करती है, लेकिन यह जवाब मुझे लगता है कि बाहर निकलना C # 'की विफलता की तरह है, इसलिए C ++ में बाहर निकलने की कोशिश अंत में निष्पादित होती है?
जिमी हॉफ़ा

@ जिमीहॉफ, सी ++ के पास नहीं हैfinally
विंस्टन ईवर्ट

6

यह ध्यान देने योग्य है कि सी मानक (C99) दो प्रकार के निष्पादन वातावरण, फ्रीस्टैंडिंग पर्यावरण और होस्टेड पर्यावरण को परिभाषित करता है । फ्रीस्टैंडिंग पर्यावरण एक सी वातावरण है जो सी पुस्तकालयों का समर्थन नहीं करता है और एम्बेडेड अनुप्रयोगों और पसंद के लिए अभिप्रेत है। एसी वातावरण जो C पुस्तकालयों का समर्थन करता है उसे होस्टेड वातावरण कहा जाता है।

C99 कहते हैं, एक फ्रीस्टैंडिंग पर्यावरण कार्यक्रम समाप्ति में कार्यान्वयन को परिभाषित किया गया है। इसलिए, यदि कार्यान्वयन परिभाषित करता है main, return nऔर exit, उनका व्यवहार उस कार्यान्वयन में परिभाषित किया गया है।

C99 होस्टेड पर्यावरण व्यवहार को परिभाषित करता है,

यदि मुख्य फ़ंक्शन का रिटर्न प्रकार इसके साथ संगत प्रकार है, तो प्रारंभिक कॉल से मुख्य फ़ंक्शन तक का रिटर्न मुख्य फ़ंक्शन द्वारा अपने तर्क के रूप में दिए गए मान के साथ निकास फ़ंक्शन को कॉल करने के बराबर है; } तक पहुँचने से जो मुख्य फ़ंक्शन को समाप्त करता है, 0. का मान लौटाता है। यदि रिटर्न प्रकार इंट के साथ संगत नहीं है, तो होस्ट वातावरण में वापस लौटी समाप्ति स्थिति अनिर्दिष्ट है।


1
और यह वास्तव में एक मुक्त वातावरण से बाहर निकलने () को कॉल करने का कोई मतलब नहीं है। बाहर निकलने के एम्बेडेड बराबर () प्रोग्राम को अनन्त लूप में लटका देना होगा, फिर वॉचडॉग का समय-समय पर इंतजार करना होगा।

0

सी मानक के दृष्टिकोण से, वास्तव में नहीं, returnएक बयान और exit()एक समारोह होने के अलावा। या तो atexit()कार्यक्रम के समापन के बाद बुलाया जाने वाले किसी भी कार्य का कारण होगा ।

ऐसी कुछ स्थितियाँ हैं जिन्हें आप देखना चाहते हैं:

  • में पुनरावृत्ति main()। जबकि व्यवहार में शायद ही कभी देखा जाता है, यह सी में कानूनी है (सी ++ स्पष्ट रूप से इसे मना करता है।)
  • का पुनः उपयोग main()। कभी-कभी किसी मौजूदा main()को कुछ और नाम दिया जाएगा और उसे नए द्वारा बुलाया जाएगा main()

exit()यदि आप कोड लिखने के बाद उन दोनों में से किसी एक में बग का उपयोग करेंगे, तो विशेष रूप से असामान्य रूप से समाप्त न होने पर। उस से बचने के लिए, यह एक अच्छा विचार है main()कि समारोह के रूप में इलाज करने की आदत हो और returnजब आप इसे समाप्त करना चाहते हों।

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