C에서 return n과 exit (n) 사이에 차이가 있습니까?


9

return n( main함수에서)와 exit(n)C 에서 차이가 있습니까? C 또는 POSIX 표준으로 정의되어 있습니까, 아니면 OS 또는 컴파일러에 의존합니까?

답변:


5

대부분의 경우,이 차이 없지만 여기 사용 여부에 따라 다르게 작동 할 가능성이 높습니다 C 프로그램의 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그에 의존해서는 안됩니다.)*argvmain()


16
  • C
    의 경우 표준에 따르면 초기 통화에서 메인 통화로 복귀하는 것은 통화 종료와 같습니다. 그러나 정리하는 동안 main에서 로컬로 데이터가 필요할 경우 main에서 리턴 할 수 없습니다.

  • C ++ 용

exit (0)을 사용하여 프로그램을 종료하면 로컬 범위의 비 정적 객체에 대한 소멸자가 호출되지 않습니다. 그러나 리턴 0이 사용되면 소멸자가 호출됩니다.

프로그램 1 –-exit (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;
}

출력 : 내부 테스트 생성자
내부 테스트 소멸자

예를 들어 소멸자에게 파일 닫기와 같은 리소스를 해제하는 코드가있는 경우 소멸자를 호출하는 것이 때때로 중요합니다.

exit ()를 호출하더라도 정적 객체는 정리됩니다. 예를 들어, 다음 프로그램을 참조하십시오.

#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);
}

출력 : 내부 테스트 생성자
내부 테스트 소멸자


파일을 닫는 것은 프로그램 종료시 파일이 닫히기 때문에 종료 할 때 발생하는 중요한 소멸자의 좋은 예는 아닙니다.
Winston Ewert

1
@WinstonEwert : True이지만 여전히 플러시해야하는 응용 프로그램 수준 버퍼가있을 수 있습니다.
Philipp

1
문제는 C ++ 어디 ... 언급하지 않습니다
tdammers

나는 어느 언어도 나를 용서하지 않는다는 것을 알고 있지만,이 대답은 exit가 C #의 페일 패스트와 같다고 생각하게합니다.
Jimmy Hoffa

@JimmyHoffa, c ++에는 없습니다finally
Winston Ewert

6

C 표준 (C99)은 독립형 환경호스팅 환경 이라는 두 가지 유형의 실행 환경을 정의한다는 점은 주목할 가치가 있습니다 . 독립형 환경은 C 라이브러리를 지원하지 않으며 임베디드 응용 프로그램 등을위한 C 환경입니다. C 라이브러리를 지원하는 AC 환경을 호스팅 환경이라고합니다.

C99에 따르면, 독립형 환경에서 프로그램 종료는 구현이 정의되어 있습니다. 따라서 구현 main에서 return n, 및를 정의 하면 exit해당 동작은 해당 구현에서 정의 된 것과 같습니다.

C99는 호스팅 환경 동작을 다음과 같이 정의합니다.

기본 함수의 리턴 유형이 호환 가능한 유형 인 경우, 초기 함수에서 기본 함수로의 리턴은 기본 함수가 리턴 한 값을 인수로 사용하여 종료 함수를 호출하는 것과 같습니다. 주 함수를 종료하는}에 도달하면 값 0이 리턴됩니다. 리턴 유형이 int와 호환되지 않으면 호스트 환경으로 리턴되는 종료 상태는 지정되지 않습니다.


1
그리고 독립 환경에서 exit ()를 호출하는 것은 실제로 의미가 없습니다. exit ()의 내장 된 기능은 프로그램을 영구 루프에 매달고 워치 독이 시간 초과 될 때까지 기다리는 것입니다.

0

C 표준의 관점에서, 실제로는 아니지만 return진술과 exit()함수 가 아닙니다 . 등록 된 모든 함수 atexit()가 호출되고 프로그램이 종료됩니다.

주의해야 할 몇 가지 상황이 있습니다.

  • 에서 재귀 main(). 실제로는 거의 보이지 않지만 C에서는 합법적입니다 (C ++에서는 명시 적으로 금지합니다).
  • 의 재사용 main(). 때로는 기존 main()이름이 다른 이름으로 바뀌어 new로 호출되기도합니다 main().

exit()코드를 작성한 후, 특히 비정상적으로 종료되지 않는 경우이 중 하나를 사용 하면 버그가 발생합니다. 이를 피하려면 main()기능 으로 처리 return하고 종료하려는 경우 사용 하는 습관을들이는 것이 좋습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.