답변:
사실, 거기에 있다 차이,하지만 미묘한입니다. C ++에는 더 많은 의미가 있지만 차이점이 중요합니다.
내가 전화를 할 경우 return
에 main()
, 소멸자는 내 로컬 범위 객체에 대해 호출됩니다. 내가 호출 할 경우 exit()
, 더 소멸자 내 로컬 범위 객체에 대해 호출되지 않습니다! 다시 읽어보세요. exit()
반환하지 않습니다 . 즉, 일단 전화를 걸면 "백시가 없습니다"라는 의미입니다. 해당 함수에서 생성 한 객체는 파괴되지 않습니다. 이것은 종종 영향을 미치지 않지만 때로는 파일을 닫는 것과 같이 영향을 미칩니다 (모든 데이터를 디스크로 플러시 하시겠습니까?).
참고 것을 static
당신이 호출하면 객체도 정리됩니다 exit()
. 마지막으로를 사용 abort()
하면 객체가 파괴되지 않습니다. 즉, 전역 객체, 정적 객체 및 로컬 객체가 없어도 소멸자가 호출됩니다.
복귀 초과 이탈을 선호 할 때는주의하여 진행하십시오.
http://groups.google.com/group/gnu.gcc.help/msg/8348c50030cfd15a
thread_local
객체의 소멸자가 호출됩니다. 다른 로컬 객체의 소멸자는 여전히 호출되지 않습니다. ideone.com/Y6Dh3f
exit()
파일을 깨끗하게 닫는 문제 는 실제로 잘못되었습니다. 즉, 하나 개를 사용하면 : 유일한 시간 데이터는 반대의 경우에 저장되지 않을 수 return
에서 main()
하나를 호출 한 setbuf()
또는 setvbuf()
버퍼가 자동 스토리지로 선언으로 main()
(아래 R.의 대답에 설명 된대로). 이 질문에는 C와 C ++ 태그가 있고 태그 스타일이 아닙니다!
또 다른 차이점
exit
은 표준 라이브러리 기능이므로 헤더를 포함하고 표준 라이브러리와 연결해야합니다. (C ++로) 설명하기 위해 이것은 유효한 프로그램입니다.
int main() { return 0; }
그러나 사용하려면 exit
다음이 포함되어야합니다.
#include <stdlib.h>
int main() { exit(EXIT_SUCCESS); }
게다가이 추가 가정을 추가 호출하는 것을 exit
에서하는 main
제로를 반환과 같은 부작용이있다. 다른 사람들이 지적했듯이, 이것은 어떤 종류의 실행 파일 (즉, 누가 호출하고 있는지)에 달려 main
있습니다. C 런타임을 사용하는 앱을 코딩하고 있습니까? Maya 플러그인? Windows 서비스? 운전자? 각 사례 exit
는에 해당 하는지 조사해야 합니다 return
. IMHO 는 실제로 의미가exit
있을 때 사용하여 코드를 더 혼란스럽게 만듭니다. OTOH, 정말로 의미 한다면 , 그것을 사용하십시오. return
exit
이 선호하는 적어도 하나의 이유는 exit
당신의 경우 atexit
처리기에 자동 저장 - 기간 데이터를 참조 main
하거나 사용하는 경우 setvbuf
또는 setbuf
표준 중 하나에 할당 자동 저장-기간에 버퍼 스트림 main
다음에서 돌아, main
생산 정의되지 않은 동작이지만 호출 exit
은 유효합니다.
또 다른 잠재적 인 사용법 (일반적으로 장난감 프로그램 용으로 예약 됨)은 재귀 적 호출이있는 프로그램을 종료하는 것입니다 main
.
main()
. 다른 것과 마찬가지로 기능입니다. 반면에 표준에 특별히 언급되어 있기 때문에 표준은 표준을 정의 main()
하고 표준과 그 주변에있는 것들 에 대해 매우 신중해야 합니다. 그러나 결국 표준은 컴파일러가 자동 저장에 대해 특별한 작업을 수행하도록 요구 하지는 않지만 ( 그렇게 해서는 안됨 ) main()
. 의견에서 언급 한 단락 아래 각주 # 11 을 읽으 십시오.
에 return
대한 표준 프로토 타입에서을 main()
반환한다고해서 항상 사용 합니다 int
.
즉, 일부 표준 버전은 main
특별한 처리 방법을 제공하며 명시적인 return
진술 이 없으면 0을 반환한다고 가정합니다 . 다음 코드가 주어진다 :
int foo() {}
int main(int argc, char *argv[]) {}
G ++는 다음에 대한 경고 만 생성 foo()
하고 누락 된 리턴을 무시합니다 main
.
% g++ -Wall -c foo.cc
foo.cc: In function ‘int foo()’:
foo.cc:1: warning: control reaches end of non-void function
return
실행을 끝내기 위해 사용해야한다는 의미는 아닙니다 . 호출 exit()
은 또한 모든 함수의 실행을 종료하는 유효하고 때로는 필요한 방법입니다. 실제로 나와 다른 사람들이 다른 곳에서 설명했듯이 전화를 걸 exit()
더라도 main()
전체 프로세스를 종료하려는 의도가 훨씬 명확 해지고 프로세스가 종료 될 때까지 자동 저장이 유지되며 향후 코드 리팩토링 동안 유지 관리가 더 쉬워집니다. 의도를 끝내기 위해 C를 사용 return
하는 main()
경우 프로세스가 나쁜 습관 일 것입니다.
나는 강력히 에서 자동 스토리지 것을 방지하기 위해 exit ()를 사용하는 방법에 대한 R.에 의해 두 번째 주석 main()
프로그램이 실제로 끝나기 전에 재생을. return X;
in 의 명령문은 main()
에 대한 호출과 정확하게 동일 하지 않습니다. 리턴 할 때 exit(X);
동적 스토리지의 동적 저장이 main()
사라지 main()
지만 exit()
대신 호출 이 이루어지면 사라지지 않습니다 .
또한 C 또는 C와 같은 언어에서는 return
명령문이 독자에게 실행이 호출 함수에서 계속 될 것이라고 강력히 암시하며,이 실행 계속은 일반적으로 main()
함수 를 호출 한 C 시작 루틴을 계산하면 기술적으로 사실이지만 그렇지 않습니다. 정확히 무엇을 당신은 당신이 프로세스를 종료하는 것을 의미 할 때 의미한다.
당신이 다른 함수 내에서 프로그램을 종료 할 경우 결국 제외하고 main()
는 합니다 전화 exit()
. 일관되게 그렇게하면 main()
코드를보다 읽기 쉽게 만들 수 있으며 누구나 코드를 쉽게 리팩터링 할 수 있습니다. 즉, main()
다른 함수로 복사 된 코드 는 호출 되어야 하는 우연한 return
진술 로 인해 오작동하지 않습니다 .exit()
따라서 이러한 모든 사항을 결합하면 결론적으로 적어도 C 는 프로그램을 끝내기 위해 명령문을 사용하는 것이 나쁜 습관 이라는 것 return
입니다 main()
.
exit()
일반적 으로 피하는 것이 좋지만 특정 컨텍스트에서 a throw
또는 abort()
대안이 작동하지 않으면 사용하십시오 . 그러나 특히 exit()
main에서는 피하고 일반적인 방법으로 main에서 return을 사용하십시오.
exit ()는 'return'이 아닌 특별한 작업을 수행합니까?
흔하지 않은 플랫폼을위한 일부 컴파일러를 사용하면 exit()
인수를 프로그램의 종료 값으로 변환 할 수 있지만 반환 main()
값은 변환없이 호스트 환경으로 직접 값을 전달할 수 있습니다.
이 경우 표준은 동일한 동작을 요구합니다 (특히, int
호환되는 것을 반환하는 것은 해당 값 main()
으로 호출 exit()
하는 것과 동일해야 함 ). 문제는 OS마다 종료 값을 해석하기위한 규칙이 다르다는 것입니다. 많은 (MANY!) 시스템에서 0은 성공을 의미하고 다른 것은 실패입니다. 그러나 VMS의 경우 홀수 값은 성공을 의미하고 하나는 실패를 의미합니다. 에서 0을 반환 main()
하면 VMS 사용자에게 액세스 위반에 대한 불쾌한 메시지가 표시됩니다. 실제로 액세스 위반은 없었습니다. 이는 단순히 실패 코드 0과 관련된 표준 메시지였습니다.
그리고 ANSI가 함께 와서 축복 EXIT_SUCCESS
과 EXIT_FAILURE
인수로 당신에게 전달할 수 있습니다 exit()
. 이 표준은 또한 exit(0)
동일하게 동작해야 exit(EXIT_SUCCESS)
하므로 대부분의 구현은에 정의 EXIT_SUCCESS
되어 0
있습니다.
따라서 표준 은 값이 0 인 오류 코드 를 리턴하는 표준 방법을 남기지 않으므로 VMS에 바인드합니다 .
따라서 1990 년대 초 VAX / VMS C 컴파일러는의 반환 값을 해석하지 않고 main()
단순히 호스트 환경에 값을 반환했습니다. 그러나 사용 exit()
했다면 표준에서 요구하는 작업을 수행 할 수 있습니다 . 성공 코드 및 일반 실패 코드로 변환 EXIT_SUCCESS
(또는 0
) EXIT_FAILURE
합니다. 사용하려면 EXIT_SUCCESS
, 당신은 했다 그것을 통과 exit()
, 당신은에서를 반환 할 수 없었다 main()
. 그 컴파일러의 최신 버전이 그 동작을 유지했는지 여부는 모르겠습니다.
휴대용 C 프로그램은 다음과 같습니다.
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Hello, World!\n");
exit(EXIT_SUCCESS); /* to get good return value to OS */
/*NOTREACHED*/ /* to silence lint warning */
return 0; /* to silence compiler warning */
}
따로 : 내가 정확하게 기억한다면, 종료 값에 대한 VMS 규칙은 홀수 / 짝수보다 더 미묘합니다. 실제로 심각도 레벨을 인코딩하기 위해 낮은 3 비트와 같은 것을 사용합니다. 그러나 일반적으로 홀수 심각도 수준은 성공 또는 기타 정보를 나타내며 짝수 레벨은 오류를 나타냅니다.
returned
을 처리했을 수도 있지만 표준에서는 " 함수 의 반환 유형이 와 호환되는 유형 인 경우 초기 호출에서 반환 된 함수는 다음과 같습니다. 함수가 인수로 반환 한 값을 사용 하여 함수 를 호출하는 것과 같습니다 . " C11입니다. C89 / C90은 거의 같은 표현을 가지고있었습니다. main
exit
main
int
main
exit
main
EXIT_SUCCESS
플랫폼 특정 실패 상태를 값 0 으로 리턴 할 방법이 없었기 때문에 ,이 시대의 일부 컴파일러가 메인에서 리턴 처리 그리고 exit()
다르게.
C에서 리턴하는 main
것은 exit
동일한 값 으로 호출하는 것과 정확히 동일합니다.
C 표준 상태의 5.1.2.2.3 절 :
main 함수의 리턴 유형이 int와 호환되는 유형 인 경우, 초기 함수에서 main 함수로의 리턴은 main 함수가 리턴 한 값을 인수로 사용하여 exit 함수를 호출하는 것과 같습니다 . 11) main 함수를 종료하는}에 도달하면 값 0이 리턴됩니다. 리턴 유형이 int와 호환되지 않으면 호스트 환경으로 리턴 된 종료 상태는 지정되지 않습니다.
C ++의 규칙은 다른 답변에서 언급했듯이 약간 다릅니다.
실제로 사이에 차이가 exit(0)
와 return(0)
에가 main
- 귀하의 경우 main
함수가 여러 번 호출됩니다.
다음 프로그램
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
if (argc == 0)
return(0);
printf("%d", main(argc - 1, argv));
}
다음으로 실행
./program 0 0 0 0
다음과 같은 결과가 나타납니다.
00000
그러나 이것은 :
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
if (argc == 0)
exit(0);
printf("%d", main(argc - 1, argv));
}
인수에 관계없이 아무 것도 인쇄하지 않습니다.
아무도 main
명시 적으로 전화하지 않을 것이라고 확신한다면 기술적으로 큰 차이는 아니지만 명확한 코드를 유지하는 exit
것이 훨씬 좋습니다. 어떤 이유로 든 전화를 원한다면 main
필요에 따라 조정해야합니다.
C에 대해 말하기