2013-08-06 2 views
0

나는 교육 목적으로 만 내 exit() 함수를 구현할 생각이었습니다. 나는 OS가 당신을 허락한다면 당신이 주소를 조작 할 수 있다는 것을 안다. (예를 들어, 운영체제가 주소 0을 조작하게하지 않으면 충돌이 일어날 것이다.)
그래서 그 주소로 0을 보내지 않으면 return 0이 반환됩니다.main()의 끝에서 C++ 반환

int main(){ 
// code... 
return 0; 
} 

return 0은 OS에 '성공'을 반환합니다. 맞습니까? 그러나 그것은 어느 주소입니까? 그것을 어떻게 얻을 수 있습니까? 그리고이 방법으로 구현 된 C 표준 라이브러리의 실제 exit()가 있습니까?

+0

귀하의 질문에 실제로 많은 의미가 없습니다. 명확하게 해봐야합니다. –

+4

"OS에서 사용자가 조작 할 수있는 이러한 주소"에 대한 오해를 저장했다고 생각합니다. – Borgleader

+0

'return 0;은'main' 함수에서'0'을 반환합니다. C++ 표준은 함수에서 반환 할 때 이동할 주소를 지정하지 않지만 일반적으로 호출 스택이나 레지스터에 저장됩니다. 일부 crt1 구현은'exit (main (argc, argc, envp))'를 사용하기 때문에 링커를 올바르게 설정하면'exit' 함수를 무시할 수 있습니다. – rightfold

답변

4

return 0 때 주소로 돌아 가지 않습니다. 값은입니다. 프로세스가 값 0을 리턴하면 정상 종료 된 것으로 간주됩니다. 호출 프로세스에서 메시지로 해석 할 수있는 0이 아닌 값 (최대 255 개)을 반환 할 수 있습니다.

예제 명령 grep foobar fubar으로 살펴 보겠습니다. 파일 fubarfoobar 패턴이 있으면 0 (성공)을 리턴합니다. 파일 fubarfoobar이 없으면 1을 리턴합니다. fubar이라는 파일이 없을 때 2를 반환합니다. rturn 값은이 명령이 실패의 성공 또는 이유를 평가하도록 만드는 스크립트에서 해석 될 수 있습니다.

+0

어쨌든 OS는 프로그램에서 값 0을 얻습니다. 이 값은 어디로 이동합니까? – Davlog

+5

@Davlog main이 호출되기 전후에 실행되는 시스템/구현 관련 코드가 있습니다. –

+0

이것은 주소가 아니며, OS는 프로세스의 프로그램/스레드를 초기화합니다. 프로그램이 닫히면 프로그램 스택의 마지막 값이 반환 값이되고 OS는 그 결과를 얻습니다. 특정 주소가 있다면 그렇게 할 수 있습니다. – Lefsler

4

종료 코드는 프로세스 제어 블록에 저장되므로 운영 체제는 결과 값을 다른 프로세스에보고 할 수 있습니다.

return 문이 작업을 수행하지 것입니다, 그러나 http://www.cs.auckland.ac.nz/compsci340s2c/lectures/lecture06.pdf

참조하십시오. 런타임 라이브러리는 실제로 더 일반적인 함수처럼 main을 호출하고 반환 값을 가져옵니다 (인텔에서는 int 유형의 반환 값이 EAX 레지스터에 저장 됨). 그러면 커널이 TCB. exit()은 커널을 호출하여 TCB의이 구성원을 작성합니다.

+0

'exit' 그리고'main'에서 돌아 오는 것은 그 이상입니다. (물론 OS가 가지고 있다고 가정하면 PCB에 직접적으로 아무것도 쓰지 않고,이 모든 것을 처리하는 리턴 코드로 OS 고유의 프리미티브를 호출한다.) –

+0

@James : 쓰기는 프로세스의 요청에 따라 커널에 의해 수행됩니다. –

+0

예.중요한 부분은 어떤 시점에서 'exit'는 커널 레벨 프리미티브를 호출하여 프로세스를 종료하도록 지시합니다. 이 커널 레벨 프리미티브는 리턴 코드 (이 커널 프리미티브에 인수로 전달됨)와 함께 PCB (또는 커널 코더가 호출하기로 결정한 것)를 업데이트 할뿐만 아니라 프로세스가 스케줄되지 않도록하는 정보로 업데이트합니다. 이 프리미티브는 프로세스의 모든 리소스를 회수하고 아마도 일부 회계 정보를 기록합니다. –

1

귀하의 혼란은 return의 이해가 없기 때문입니다. 예를 들어이 기능을 가지고 :

int add(int x, int y) 
{ 
    return (x + y); 
} 

위의 함수에서 반환하고 main 함수의 끝에 반환 문이 정확히 언어의 관점는 같은 의미에서 , 동일합니다. 그 의미는 호출자에게 정수를 반환하는 것입니다. 호출자가이 값에서 얻는 값은 호출자가 함수를 호출 할 의도에 따라 완전히 다른 것입니다. add(7, 9);에 전화하여 2 개의 GPA 성적을 추가하는 동안 다른 프로그래머가 두 개의 은행 계좌에서 모든 금액의 합계를 찾을 수 있다고 말하십시오.

이제 main은 운영 체제 또는 더 구체적으로 로더가 프로그램이되도록 호출하는 첫 번째 기능이므로 특수 기능으로 처리됩니다. 프로그램이 완료된 후, main이 반환하는 것은 OS의 의미에 기반한 모든 것을 의미 할 수 있습니다. 이 값은 메모리 주소와 아무 관련이 없습니다.

옆 : 표준에 따르면 C++ (및 C99 onawards)에서는 return 0; 문을 생략하여 프로그램을 성공적으로 종료 할 수 있습니다.

+0

그것은 C의 버전에 달려 있지 않습니까? –

+0

@BenVoigt No .... –

+0

@BenVoigt : 주말이 끝날 때'return 0; '이 누락되었다는 뜻입니까? – legends2k

2

mainreturn 0;return과 같이 작동합니다. 그것 그것이 호출 된 곳으로 돌아갑니다. 이 프로그램 시작하면 시스템이 main에 그것을 시작하지 않지만, 초기화를 많이하지 않습니다 일부 시동 주소와 같은 다음 일 : 즉

exit(main(/*...*/)); 

, main에서 반환을 시뮬레이션하지 않습니다. main에서 다시 전화하면 exit가됩니다. 그리고 시스템 종료를 알리는 (Unix에서는 _exit) 시스템 특정 함수를 호출하기 전에 exit를 실행 한 다음 을 종료합니다.

당신은 당신이 필요로하는 정보를 찾는 수있는 방법이 없기 때문에, exit을 직접 구현할 수 없습니다 : 필요 atexit 등록 기능 의 목록을 정적 수명 등을 가진 객체의 소멸자의 목록을 호출 할

+0

«직접 이탈을 구현할 수는 없습니다»- 틀림! 누군가 다른 사람이 그랬다면 당신도 그것을 확실히 할 수 있습니다. 결국, 당신은'exit()'에 대한 호출을 가로 채고 당신 자신의 구현을 제공 할 수있다. –

+0

@VladLazarenko 내가 열거 한 이유 때문에 스스로 exit을 구현할 수는 없습니다. 'exit'는 단지 시스템으로 돌아 오는 것 이상을 수행합니다. 청소해야합니다. 그리고해야 할 일의 목록은 액세스 할 수있는 외부 기호가 아니며 외부에서 정의 된 구조가 없으므로 사용자가 수행해야 할 작업을 알 수 있습니다. 'exit'은 나머지 C 런타임 라이브러리와 작동하며'exit'을 구현하려면 C 런타임 라이브러리의 소스가 필요합니다. –

+0

표준 라이브러리와 관련이 없지만 선택의 C++ ABI 라이브러리에 구현 된 'atexit'이라는 사실을 설명하는 것이 중요하다고 생각합니다. 즉, 거기에있을 수있는 상징이 아니며, 플랫폼 별. – user2485710

0

미터 이해가 올바른 경우 PCB가 커널에 의해 파괴 될 때 ...이 ... 일해야한다 반환 값을 포함 주요 쉘 출구로 전송 될 것 SIGCHLD 신호가 될 것입니다

하지만 특정 기능을 종료하는 동안 특정 기능을 연결하려면 코드에서 POSIX 구현에 따라 atexit()에서 핸들러를 등록 할 수 있습니다.

프로그램의 제어가 다른 프로세스에서 PC에 도달했기 때문에 리턴 밸러가 사용자 레벨에서 어떻게 전파되는지 수정할 수 있다고 생각하지 않습니다. 당신은 접근 할 수 없다). 당신의 C++ ABI 라이브러리가 기호 __cxa_atexit를 구현하는 경우

+0

PCB는 '대기'에 의해 수확 될 때까지 커널에 의해 파괴되지 않습니다. –

0

당신은 언어가 정말 프로그램이 실행을 중지 할 때 사용자 정의 뭔가를 할 수있는 다른 안전한 방법을 제공하지 않습니다 AFAIK atexit

를 사용할 수 있습니다.

0

function이 있으면 해당 유형이 있습니다. int, void 또는 기타 일 수 있습니다. 함수가 void가 아닌 경우에는 값을 반환해야합니다. 우리의 경우, 값이 main이면 int이며, 보통 return 코드입니다. 규칙은 0이면 오류가없고 다른 값은 오류 코드입니다.

2

여기에있는 주된 혼란은 그 main이 C++ 프로그램에서 처음이자 마지막으로 일어나는 것이라는 생각입니다. [1] 당신의 프로그램의 첫 부분인데, 보통 몇 가지 사항을 설정하고, 명령 행 인수를 분석하고, 표준 I/O (cin, cout 등)를 열거 나 초기화하는 코드가 있습니다. 그런 일이 발생하기 전에 main가 호출됩니다. 그리고 main은 "main 전에 문제를 해결"하는 C++ 런타임 기능에 의해 호출되는 본질적으로 또 다른 함수입니다.

따라서 main이 반환되면 코드를 호출 한 코드로 돌아가서 정리 작업이 필요합니다 (표준 I/O 채널 및 기타 여러 가지 작업 완료). 실제로 마무리 작업을 수행하기 전에 일부 OS 기능을 호출하여 "이 프로세스를 종료합니다". 이 "프로세스 종료"기능의 일부로 OS에 "성공 또는 실패"신호를 보내는 방법이 (대부분의 OS에서) 있으므로 응용 프로그램을 모니터링하는 다른 프로세스에서 "모두 정상적으로 작동하는지 확인"할 수 있습니다. 결국 0 (또는 mainreturn 1;을 사용하는 경우 1)이 종료됩니다.

[1] 사용자 코드의 일부인 생성자와 정적 개체가있는 경우 main [또는 적어도 사용자 응용 프로그램에 속한 main의 코드]에있는 코드가 수행되기 전에 이러한 코드가 수행됩니다. 실행.

관련 문제