Main() 의 return 0
gisman
이 글은 main 함수의 return 0; 이 어떤 의미를 갖는건지 call stack을 통해 설명한다.
프갤에서 자주 보는 질문에 대해서 정리 함 하려고.. 개념탑재한 햏들이 잘 보완해줄꺼라 믿고 썰을 함 풀어볼께.
자주 보는 질문의 유형은 이래..
- main() 에서 return 0; 왜 해주느냐?
- return 0 하면 어떤 놈이 리턴값을 받냐?
- 0을 return 하면 FALSE를 리턴한다는건데 에러라는 얘기 아니냐?
이런 질문이 자주 나오는걸 보면 프갤에 오는 젊은훃들은 기본 자세가 되어 있는것 같아.
숙제 풀어달라고 올리는 새퀴들만 있으면 무슨 재미가 있겠어? 원리를 알고자 하는 훃들의 눈은 반짝반짝 빛나고 있을것 같아.
자 그럼 그림을 함 보자고..
화면 아랫쪽에 보이는게 Call Stack이라는 거야.
함수가 다른 함수를 부르고 또 그 안에서 다른 함수를 부르면 Call 한 경로가 Stack에 쌓여.
항상 Stack의 가장 위에는 현재 실행되고 있는 함수가 있고, 가장 아래에는 OS가 있어.
이 그림에서 보면
main의 line 10 이 가장 위에 있지? main 함수가 현재 실행중이야. 브레이크포인트가 걸려 있는 10번째 줄을 실행하려고 하는 상태야.
가장 아래에는 KERNEL32가 있어. 이걸 OS라고 보면 돼.
윈도에서 VC로 짠 예제라서 중간에 mainCRTStartup 이 껴 있어.
즉 OS에서 mainCRTStartup을 먼저 불러서 커맨드창을 표시하게 한 다음에 (스택에 쌓이겠지?)
main 을 불러준거야.
그럼 main이 0을 리턴하면 화면에 보이듯 오른쪽 위에 있는
mainret = main(__argc, __argv, _environ);
으로 전달이 되는거지.
즉 mainCRTStartup() 함수가 이 값(return 0)을 받는거야.
그 다음 main함수가 종료될테고 call stack에서 main은 제거되겠지.
이제 mainCRTStartup()가 KERNEL한테 main이 리턴한 값을 전달해 주고 종료되는 일이 남았는데, 코드를 잘 따라가 보면 exit(mainret);를 부르고, 화면에는 안 나와 있지만 디버그 기능을 이용해서 쫒아가보면(이럴 때 사용하는게 Trace Into...) ExitProcess(code); 를 호출하고 나서 mainCRTStartup()함수가 끝나.
그럼 Call stack에 KERNEL만 남게 되고 결국 KERNEL이 main이 return한 0을 mainCRTStartup을 거쳐서 받게 되는거야.
main이 리턴한 0을 받는 놈이 누구냐에 대한 해답은 나온것 같고,
나머지 질문에 대해서는 직접 찾아봐야지 뭐.
구글에서 "DOS Exit code"라고 검색해서 잘 정리된 사이트를 하나 발견했으니까 잘 봐봐.
http://mwultong.blogspot.com/2006/07/error-level-errorlevel.html
정리하자면 :
- 에러 없으면 0 리턴. 이건 규약이니까 이해하지 말고 외워서 무조건 지키면 돼.
- 에러 있으면 0말고 다른 값 리턴.
만약 0이 아닌 값을 리턴할 수 있는 프로그램을 만들었다고 해.
리턴할 수 있는 값들은 1, 2, 3 이야.
그럼 누군가 이 프로그램을 사용할텐데 뭔가 에러가 났을 때 에러원인을 찾을 수 있도록 정보를 제공해주는게 바로 exit code라는 것이고 개발자가 정하면 돼.
예를 들어 1리턴되면 "파일을 찾을 수 없음", 2면 "디스크 공간 부족", 3이면 "파일을 읽을 수 없음" 이라고 정했다고 쳐.
이렇게 해 놓고 끝이 아니야. 이걸 다른 사용자들에게 알려줄 의무가 있어.
문서나 "command /?"쳤을 때 나오는 usage message를 통해서 알려주는게 좋겠지. (유닉스면 man 에 포함시키면 되고....)
아 밥먹을 시간이다. 프로젝트 끝나니까 한가해져서 좋네. 다들 힘내~
2007년 3월 21일

