Namespaces
Variants

std:: exit

From cppreference.net
Utilities library
헤더 파일에 정의됨 <cstdlib>
void exit ( int exit_code ) ;
(C++11 이전)
[ [ noreturn ] ] void exit ( int exit_code ) ;
(C++11 이후)

정상적인 프로그램 종료를 발생시킵니다.

여러 가지 정리 단계가 수행됩니다:

1) 정적 저장 기간을 가진 객체들은 파괴되고 std::atexit 를 호출하여 등록된 함수들이 호출됩니다:
a) 정적 저장 기간을 가진 비지역 객체들은 생성자 완료의 역순으로 파괴됩니다.
b) std::atexit 로 등록된 함수들은 등록 순서의 역순으로 호출되지만, 등록 시점에 이미 호출된 이전에 등록된 함수들보다 나중에 호출됩니다.
c) std::atexit 로 등록된 각 함수 f 와 정적 저장 기간을 가진 각 비지역 객체 obj 에 대해,
  • 만약 f obj 의 초기화 전에 등록되었다면, f obj 의 파괴 후에만 호출됩니다;
  • 만약 f obj 의 초기화 후에 등록되었다면, f obj 의 파괴 전에만 호출됩니다.
d) 정적 저장 기간을 가진 각 지역 객체 obj 에 대해, obj 의 생성자 완료 시점에 obj 의 소멸자를 호출하는 함수가 std::atexit 로 등록된 것처럼 파괴됩니다.
(until C++11)
1) 현재 스레드와 연관된 스레드 지역 저장 기간 을 가진 객체들의 소멸자, 정적 저장 기간을 가진 객체들의 소멸자, 그리고 std::atexit 로 등록된 함수들은 다음 보장들을 유지하면서 동시에 실행됩니다:
a) 스레드 지역 객체에 대한 마지막 소멸자는 정적 객체에 대한 첫 번째 소멸자보다 순서가 지정됩니다 .
b) 스레드 지역 또는 정적 객체 A의 생성자 또는 동적 초기화 완료가 스레드 지역 또는 정적 객체 B보다 순서가 지정되었다면, B의 파괴 완료는 A의 파괴 시작보다 순서가 지정됩니다.
c) 정적 객체 A의 초기화 완료가 어떤 함수 F에 대한 std::atexit 호출보다 순서가 지정되었다면, 종료 과정에서의 F 호출은 A의 파괴 시작보다 순서가 지정됩니다.
d) 어떤 함수 F에 대한 std::atexit 호출이 정적 객체 A의 초기화 완료보다 순서가 지정되었다면, A의 파괴 시작은 종료 과정에서의 F 호출보다 순서가 지정됩니다.
e) 어떤 함수 F1에 대한 std::atexit 호출이 어떤 함수 F2에 대한 std::atexit 호출보다 순서가 지정되었다면, 종료 과정에서의 F2 호출은 F1 호출보다 순서가 지정됩니다.
(since C++11)
  • 위에서,
  • atexit 에 등록된 함수 또는 정적/스레드-로컬 객체의 소멸자가 예외를 발생시키는 경우, std::terminate 가 호출됩니다.
  • 컴파일러가 객체의 동적 초기화를 비-로컬 초기화 의 정적 초기화 단계로 승격시키기로 선택한 경우, 소멸 순서는 해당 객체의 가상 동적 초기화 순서를 따릅니다.
  • 함수-로컬 (블록-범위) 정적 객체가 소멸된 후, 다른 정적 객체의 소멸자에서 해당 함수를 호출하고 제어 흐름이 해당 객체의 정의를 통과하는 경우 (또는 포인터나 참조를 통해 간접적으로 사용되는 경우), 동작은 정의되지 않습니다.
  • 함수-로컬 (블록-범위) 정적 객체가 클래스 또는 배열의 하위 객체 생성 중에 초기화된 경우, 해당 클래스의 모든 하위 객체 또는 해당 배열의 모든 요소가 소멸된 후에만 소멸됩니다.
2) 모든 C 스트림이 플러시되고 닫힙니다.
3) std::tmpfile 에 의해 생성된 파일들이 제거됩니다.
4) 제어가 호스트 환경으로 반환됩니다. 만약 exit_code 0 이거나 EXIT_SUCCESS 인 경우, 성공적인 종료를 나타내는 구현 정의 상태가 반환됩니다. 만약 exit_code EXIT_FAILURE 인 경우, 비성공적인 종료를 나타내는 구현 정의 상태가 반환됩니다. 다른 경우에는 구현 정의 상태 값이 반환됩니다.

스택이 풀리지 않습니다: 자동 storage duration 을 가진 변수들의 소멸자들이 호출되지 않습니다.

목차

main 함수와의 관계

main 함수 에서 반환될 때, return 문을 통해 또는 함수의 끝에 도달함으로써 정상적인 함수 종료를 수행합니다(자동 저장 기간 을 가진 변수들의 소멸자를 호출). 그런 다음 std::exit 를 실행하며, return 문의 인수(또는 암시적 반환이 사용된 경우 0 )를 exit_code 로 전달합니다.

매개변수

exit_code - 프로그램의 종료 상태

반환값

(없음)

예제

#include <cstdlib>
#include <iostream>
struct Static
{
    ~Static() 
    {
        std::cout << "Static destructor\n";
    }
};
struct Local
{
    ~Local() 
    {
        std::cout << "Local destructor\n";
    }
};
Static static_variable; // 이 객체의 소멸자는 *호출됨*
void atexit_handler()
{
    std::cout << "atexit handler\n";
}
int main()
{
    Local local_variable; // 이 객체의 소멸자는 호출 *안됨*
    const int result = std::atexit(atexit_handler); // 핸들러가 호출됨
    if (result != 0)
    {
        std::cerr << "atexit registration failed\n";
        return EXIT_FAILURE;
    }
    std::cout << "test\n";
    std::exit(EXIT_FAILURE);
    std::cout << "this line will *not* be executed\n";
}

출력:

test
atexit handler
Static destructor

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
LWG 3 C++98 정리 과정 중 (1) 함수가
std::atexit 에 등록되거나 (2) 정적 지역 객체가 초기화될 때
동작이 불명확했음
명확히 규정됨

참고 항목

비정상적인 프로그램 종료를 유발합니다 (정리 작업 없이)
(함수)
std::exit() 호출 시 실행될 함수를 등록합니다
(함수)
(C++11)
완전한 정리 작업 없이 빠른 프로그램 종료를 유발합니다
(함수)
std::quick_exit 호출 시 실행될 함수를 등록합니다
(함수)