C와 C ++에서 main ()은 무엇을 반환해야합니까?


695

28
나는 아직도 그것이 너무 모호하다고 생각합니다. 나를 위해 "가장 효율적"을 정의하십시오. 어떤 의미에서 효율적입니까? 적은 메모리를 사용한다는 의미에서? 더 빠른 달리기의 의미? 유용한 답변을 볼 수는 있지만 여전히 질문이 잘못 표시되어 있다고 생각합니다.
Onorio Catenacci

7
피쉬 포쉬 (Pish posh), 효율적인 맥락은 특히 여기에서 명백하다 ( '효율적인'의 정의를 명확히 할 수있는 예). 불완전한 버퍼가 구멍을 뚫고 나오지 않았 으면 좋겠다. void 또는 int에 관계없이 값이 반환되므로 파일 크기, 실행 된 작업 또는 할당 된 메모리에 영향을 미치지 않습니다. 그리고 대부분의 OS에서 사람들은 성공하면 0을, 다른 성공이나 실패에는 다른 것을 반환하는 경향이 있지만 표준은 없습니다. 궁극적으로, 명백한 방식으로 효율성의 차이는 없습니다.
Kit10

"정확한 (가장 효율적인)"의미가 없습니다. 하나는 효율적이고 다른 것은 맞습니다. main한 번만 호출됩니다 (C ++에서는 한 번만 호출 할 수 있음 : 재귀 없음). 에서 실행하는 데 많은 시간을 소비하지 않으려면 main프로그램을 여러 번 호출하지 마십시오. 프로그램이 반복을 구현하도록합니다.
Kaz

2
내가 알 수있는 한, 그 답들 중 어느 것도 그 #include진술을 포함한 완전한 실례를 보여주지 못한다는 것이 흥미 롭다 .
puk

3
OS가없는 플랫폼에서는 반환 값이 의미가 없습니다. 당신은 아무것도 반환하지 않습니다. 당신이 충돌하는 경우 returnmain(...)임베디드 장치에서, 시스템은 예측할 수없는 상태로 진행하고 세탁기는 자기 인식이되어 당신을 죽일하려고합니다. 그래서 우리 void main()는이 경우에 사용합니다. 이것은 베어 메탈 임베디드 산업 표준 관행입니다.
3Dave

답변:


570

의 반환 값 main은 프로그램이 종료 된 방법 을 나타냅니다. 정상 종료는의 0 반환 값으로 표시됩니다 main. 비정상 종료는 0이 아닌 리턴에 의해 표시되지만 0이 아닌 코드를 해석하는 방법에 대한 표준은 없습니다. 다른 사람들이 지적했듯이 void main()C ++ 표준에 의해 금지되어 있으므로 사용해서는 안됩니다. 유효한 C ++ main서명은 다음과 같습니다.

int main()

int main(int argc, char* argv[])

어느 것이

int main(int argc, char** argv)

또한 C ++에서는 int main()return-statement없이 남겨 둘 수 있으며이 시점에서 기본값은 0을 반환합니다. 이는 C99 프로그램에서도 마찬가지입니다. return 0;생략해야하는지 여부 는 논쟁의 여지가 있습니다. 유효한 C 프로그램 기본 서명의 범위는 훨씬 큽니다.

효율성은 main기능에 문제가되지 않습니다 . C ++ 표준에 따라 한 번만 입력하고 남겨 둘 수 있습니다 (프로그램 시작 및 종료 표시). C의 경우, 재 입력 main()이 허용되지만 피해야합니다.


69
메인 CAN은 여러 번 들어 오거나 떠날 수 있지만,이 프로그램은 디자인 상을 수상하지 못할 것입니다.)
korona

13
또한 C99에는 main () 함수의 끝에 도달하는 것이 0을 반환하는 것과 동일하다는 C ++의 잘못된 기능이 있습니다. main ()이 int와 호환되는 유형을 반환하도록 정의 된 경우 (섹션 5.1.2.2.3).
Jonathan Leffler

62
다시 들어가는 main은 유효한 C ++이 아닙니다. 명시 적으로 표준에서 3.6.1.3은 '프로그램 내에서 main을 사용해서는 안된다'고 명시합니다.
workmad3

117
stdlib.h는 이러한 목적으로 EXIT_SUCCESS 및 EXIT_FAILURE를 제공합니다.
Clay

20
0과 0이 아닌 것은 정확하지만 코드를 읽는 사람에게는 전혀 의미가 없습니다. 이 질문은 사람들이 유효한 / 무효 코드가 무엇인지 모른다는 증거입니다. EXIT_SUCCESS / EXIT_FAILURE가 훨씬 더 명확합니다.
JaredPar

169

허용 된 답변은 C ++을 대상으로하는 것으로 보이므로 C와 관련된 답변을 추가 할 것이라고 생각했는데 몇 가지면에서 다릅니다.

ISO / IEC 9899 : 1989 (C90) :

main() 다음 중 하나로 선언되어야합니다.

int main(void)
int main(int argc, char **argv)

또는 동등합니다. 예를 들어 int main(int argc, char *argv[])두 번째 것과 같습니다. 또한 int반환 유형은 기본값이므로 생략 할 수 있습니다.

구현이 허용하는 경우 main()다른 방법으로 선언 할 수 있지만 이로 인해 프로그램 구현이 정의되고 더 이상 엄격하게 준수하지 않습니다.

이 표준은 엄격하게 준수하는 (즉, 정의 된 구현 동작에 의존하지 않음) 반환 0EXIT_SUCCESS성공적인 종료 및 EXIT_FAILURE실패한 종료에 대한 3 개의 값을 정의 합니다. 다른 값은 비표준이며 구현이 정의되어 있습니다. 정의되지 않은 동작을 피하려면 끝에 main()명시적인 return진술 이 있어야합니다 .

마지막으로, 표준 관점 main()에서 프로그램 을 호출 할 때 아무런 문제가 없습니다 .

ISO / IEC 9899 : 1999 (C99) :

C99의 경우 다음을 제외하고 모든 것이 위와 동일합니다.

  • int반환형는 생략 될 수 없다.
  • 에서 return 문을 생략 할 수 있습니다 main(). 당신이하고 main()끝내면 암시 적 return 0입니다.

1
@Lundin 나는 누군가가 비표준 준수 프로그램을 허용하는 컴파일러를 만들거나 비 표준 준수 컴파일러를 가질 수 있다고 인용 할 필요가 없다고 생각합니다. 그것은 상식과 상식입니다
KABoissonneault

4
@KABoissonneault 구현 정의 동작은 완전히 문서화되지 않은 동작과 달리 표준의 용어입니다. 구현 정의 동작으로 나열된 것을 구현하면 여전히 표준을 따릅니다. 이 경우 인용 된 C89는 이러한 구현 정의 동작을 나열하지 않으므로 인용을 할 필요가 없습니다.
Lundin

1
@Lundin 당신은 이것을 잘못된 길로보고 있습니다. 우리가 말하는 것은 구현 정의 된 행동이 아니라 표준에서 선택하는 구현에서 표준에서 벗어난 구현에 대해 이야기하는 것입니다. 부모에게 불순종하는 자녀와 비슷합니다. 부모가 한 말에 대해 자녀가 어떤 방식으로 갈 수 있는지 알려주기 위해 부모의 인용이 필요하지 않습니다. 당신은 아이가 그렇게하기로 결정한 순간, 더 이상 부모의 길을 따르지 않는다는 것을 알고 있습니다.
KABoissonneault

2
@KABoissonneault 내 의견에서 인용 한 부분은 구현 정의 동작에 관한 것입니다 ( 비표준 컴파일러 확장 과 반대 입니다). 따라서 구현 정의 동작에 대해 이야기하고 있습니다. 다른 것에 대해 독백을하고 있다면 운이 좋을 것입니다.
Lundin

1
내가 인용의 표현은 (그들이 말하는 "그러나이 정의 프로그램 구현하게"부분을) 혼란 생각하지만 난 @Lundin는 IF "에서 말했듯이 확신하는 사람은 (표준이 아닌 행동에 대해 얘기했다 구현 실제 구현 정의 동작과 달리 "및"더 이상 엄격하게 표준을 준수하지 않습니다 "). 그 사람은 반드시 자신의 대답을 다시 말해야하지만, 여전히 표준에 대한 인용이 필요하다고 생각하지 않습니다.
KABoissonneault

117

표준 C — 호스팅 환경

호스팅 환경 (일반적인 환경)의 경우 C11 표준 (ISO / IEC 9899 : 2011)은 다음과 같이 말합니다.

5.1.2.2.1 프로그램 시작

프로그램 시작시 호출 된 함수의 이름은 main입니다. 구현은이 함수에 대한 프로토 타입을 선언하지 않습니다. 반환 유형 int과 매개 변수없이 정의해야합니다 .

int main(void) { /* ... */ }

또는 두 개의 매개 변수가있는 경우 (여기서 as argc및 참조) argv, 선언 된 함수의 로컬 이름이므로 모든 이름을 사용할 수 있습니다.

int main(int argc, char *argv[]) { /* ... */ }

또는 동등한 것; 10) 또는 다른 구현 정의 방식으로.

이들이 선언되면, main 함수에 대한 매개 변수는 다음 제약 조건을 따라야합니다.

  • 의 가치 argc 음수가 아니어야한다.
  • argv[argc] 널 포인터이어야한다.
  • 의 값 argc이 0보다 크면 배열 멤버 argv[0]argv[argc-1] 논리합 프로그램을 시작하기 전에 호스트 환경 구현 정의 값을 주어진 문자열에 대한 포인터를 포함한다. 호스팅 환경의 다른 곳에서 프로그램을 시작하기 전에 결정된 프로그램 정보를 제공하기위한 것입니다. 호스트 환경에서 대문자와 소문자로 문자열을 제공 할 수없는 경우 구현시 문자열을 소문자로 수신해야합니다.
  • 의 값 argc이 0보다 큰 경우 by가 가리키는 문자열 argv[0] 은 프로그램 이름 을 나타냅니다. argv[0][0]프로그램 이름을 호스트 환경에서 사용할 수없는 경우 널 문자 여야합니다. 의 값 argc이 1보다 크면, argv[1]통해 지정된 문자열 argv[argc-1] 은 프로그램 매개 변수 를 나타냅니다.
  • 어레이가 가리키는 파라미터 argcargv문자열은 argv프로그램에 의해 수정 가능해야하며 프로그램 시작과 프로그램 종료 사이에 마지막으로 저장된 값을 유지해야합니다.

10) 따라서 int로 정의 된 typedef 이름으로 대체 int하거나 유형을 argvchar **argv등 으로 쓸 수 있습니다 .

C99 또는 C11의 프로그램 종료

에서 반환 된 값 main()은 구현 정의 방식으로 '환경'으로 전송됩니다.

5.1.2.2.3 프로그램 종료

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

11) 6.2.4에 따라, 자동 저장 기간이 선언 된 객체의 수명은 main 전자의 경우에는 없었지만, 전자의 경우에는 끝났다.

참고 0'성공'으로 의무화된다. 원할 경우 EXIT_FAILUREand EXIT_SUCCESS를 사용할 수 <stdlib.h>있지만 0은 잘 설정되어 있으며 1도 마찬가지입니다. 참조 255보다 큰 종료 코드-가능합니까? .

C89 (및 Microsoft C)에서는 main()함수가 리턴하지만 리턴 값을 지정하지 않으면 어떻게되는지에 대한 설명이 없습니다 . 그러므로 그것은 정의되지 않은 행동으로 이어진다.

7.22.4.4 exit기능

¶5 마지막으로 제어는 호스트 환경으로 돌아갑니다. 의 값 status이 0 또는 인 EXIT_SUCCESS경우, 구현 성공 상태의 구현 정의 양식 이 리턴됩니다. 의 값 statusEXIT_FAILURE인 경우 구현이 정의한 상태 실패 상태의 종료 가 반환됩니다. 그렇지 않으면 반환 된 상태는 구현 정의입니다.

표준 C ++ — 호스팅 환경

C ++ 11 표준 (ISO / IEC 14882 : 2011)은 다음과 같이 말합니다.

3.6.1 주요 기능 [basic.start.main]

¶1 프로그램은 main이라는 글로벌 기능을 포함해야하며, 프로그램의 지정된 시작입니다. [...]

¶2 구현은 주요 기능을 미리 정의하지 않아야한다. 이 기능은 과부하되지 않아야한다. int 타입의 리턴 타입을 가져야하지만 그렇지 않으면 타입이 구현 정의됩니다. 모든 구현은 다음 main 정의를 모두 허용해야합니다.

int main() { /* ... */ }

int main(int argc, char* argv[]) { /* ... */ }

후자의 형식 argc은 프로그램이 실행되는 환경에서 프로그램에 전달 된 인수의 수입니다. 경우 argc이러한 인수를 공급해야한다 제로 이외의 argv[0] 를 통해 argv[argc-1]널 (null)로 종료되는 멀티 바이트 문자열의 첫 문자 (NTMBSs) (17.5.2.1.4.2)에 대한 포인터로와 argv[0]하는 데 사용되는 이름을 나타내는 NTMBS의 초기 문자에 대한 포인터한다 프로그램을 호출하십시오 "". 의 값은 argc음수가 아니어야한다. 의 값은 argv[argc] 0이어야한다. [참고 : 이후에 (선택적) 파라미터를 더 추가 할 것을 권장한다 argv. — 끝 노트]

¶3 기능 main은 프로그램 내에서 사용되지 않아야합니다. 연계 (3.5) main는 구현에 따라 정의됩니다. [...]

¶5 main의 return 문은 main 함수를 떠나고 (자동 저장 시간이있는 객체를 파괴 함) std::exitreturn 값을 인수로 호출 하는 효과가 있습니다. 리턴 문이 발생하지 않고 제어가 메인의 끝에 도달하면 그 결과는 실행의 효과입니다

return 0;

C ++ 표준은 명시 적으로 "[주 함수]는 유형의 리턴 유형을 가져야 int하지만 그렇지 않은 경우 유형이 구현 정의됩니다"라고 명시하고 C 표준과 동일한 두 서명을 옵션으로 지원해야합니다. 따라서 'void main ()'은 C ++ 표준에서 직접 허용되지 않지만 대안을 허용하는 비표준 구현을 중지하는 방법은 없습니다. C ++는 사용자가 호출 할 main수 없도록합니다 (그러나 C 표준은 그렇지 않습니다).

C ++ 11 표준 에는 §7.22.4.4의 단락과 동일한 §18.5 시작 및 종료 단락이 있습니다.exit 기능 C11 표준에서 (위 인용)은 (따로 각주에서, 이는 단순히 문서 그 EXIT_SUCCESSEXIT_FAILURE정의 에서 <cstdlib>).

표준 C — 공통 확장

일반적으로 Unix 시스템은 세 번째 변형을 지원합니다.

int main(int argc, char **argv, char **envp) { ... }

세 번째 인수는 null로 끝나는 문자열에 대한 포인터 목록으로, 각각 이름, 등호 및 값 (비어있을 수 있음)을 갖는 환경 변수입니다. 이것을 사용하지 않으면 여전히 ' extern char **environ;' 를 통해 환경에 도달 할 수 있습니다 . 이 전역 변수는이를 선언하는 헤더가 없다는 점에서 POSIX의 고유 변수입니다.

이는 C 표준에 의해 부록 J에 문서화되어있는 공통 확장명으로 인식됩니다.

J.5.1 환경 인수

¶1 호스트 된 환경에서, main 함수는 char *envp[]에 대한 널로 끝나는 포인터 배열을 가리키는 세 번째 인수를받습니다. char각 포인터 는 프로그램의이 실행을위한 환경에 대한 정보를 제공하는 문자열을 가리 킵니다 (5.1. 2.2.1).

마이크로 소프트 C

마이크로 소프트 VS 2010 컴파일러는 흥미 롭다. 웹 사이트는 말합니다 :

main의 선언 구문은

 int main();

또는 선택적으로

int main(int argc, char *argv[], char *envp[]);

또는 mainwmain함수를 반환으로 선언 할 수 있습니다 void(반환 값 없음). void 를 선언 main하거나 wmain리턴하면 return 문을 사용하여 종료 코드를 상위 프로세스 또는 운영 체제에 리턴 할 수 없습니다. main또는 wmain로 선언 되었을 때 종료 코드를 반환하려면 함수 void를 사용해야합니다 exit.

프로그램 void main()이 종료 될 때 어떤 결과가 발생하는지 (부모 또는 OS에 어떤 종료 코드가 반환되는지) 명확하지 않으며 MS 웹 사이트도 자동입니다.

흥미롭게도 MS는 main()C 및 C ++ 표준에 필요한 두 가지 인수 버전을 규정하지 않습니다 . char **envp환경 변수 목록에 대한 포인터 인 세 번째 인수가있는 세 가지 인수 형식 만 규정 합니다.

Microsoft 페이지에는 다른 대안도 있습니다. wmain() 이 방법은 넓은 문자열을 사용하며 그 있습니다.

이 페이지 의 Microsoft Visual Studio 2005 버전은 대안으로 나열되지 않습니다 . 버전의 마이크로 소프트 비주얼 스튜디오 2008 년 이후 않습니다.void main()

표준 C — 독립형 환경

앞서 언급했듯이 위의 요구 사항은 호스팅 된 환경에 적용됩니다. 독립 환경 (호스트 환경의 대안)으로 작업하는 경우 표준에 대한 언급이 훨씬 적습니다. 독립형 환경의 경우 프로그램 시작시 호출 된 함수를 호출 할 필요 main가 없으며 리턴 유형에 대한 제한이 없습니다. 표준은 말한다 :

5.1.2 실행 환경

독립형 및 호스팅의 두 가지 실행 환경이 정의됩니다. 두 경우 모두, 지정된 C 함수가 실행 환경에 의해 호출 될 때 프로그램 시작이 발생합니다. 정적 저장 기간을 가진 모든 객체는 프로그램 시작 전에 초기화되어야합니다 (초기 값으로 설정). 그러한 초기화의 방식 및 타이밍은 달리 명시되지 않는다. 프로그램 종료는 제어를 실행 환경으로 되돌립니다.

5.1.2.1 독립 환경

C 환경에서 운영 체제의 이점없이 C 프로그램이 실행될 수있는 독립 환경에서는 프로그램 시작시 호출되는 함수의 이름과 유형이 구현 정의됩니다. 조항 4에 의해 요구되는 최소 세트 이외의 독립 프로그램에 이용 가능한 모든 도서관 시설은 구현에 따라 정의됩니다.

독립 환경에서 프로그램 종료의 영향은 구현 정의됩니다.

조항 4 적합성에 대한 상호 참조는 다음과 같습니다.

¶5 엄격하게 준수하는 프로그램 은이 국제 표준에 명시된 언어 및 라이브러리의 기능 만 사용해야합니다. 3) 지정되지 않거나 정의되지 않은 또는 구현 정의 된 동작에 따라 출력을 생성하지 않아야하며 최소 구현 제한을 초과해서는 안됩니다.

¶6 준수 구현의 두 가지 형태는 호스팅 되고 독립형 입니다. 준수 호스팅 구현은 어떤 엄격하게 준수 프로그램을 수용하여야한다. 준수 자립 구현 라이브러리 절 (7 절)에 지정된 기능의 사용이 표준 헤더의 내용에 국한되는 모든 엄격히 준수 프로그램을 수용하여야한다 <float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h>,와 <stdnoreturn.h>. 적합한 구현은 엄격하게 준수하는 프로그램의 동작을 변경하지 않는 한 확장 (추가 라이브러리 기능 포함)을 가질 수 있습니다. 4)

¶7 준수 프로그램 은 준수 구현에 허용되는 프로그램 입니다. 5)

3) 엄격하게 준수하는 프로그램은 관련 매크로를 사용하여 적절한 조건부 포함 전처리 지시문에 의해 보호되는 경우 조건부 기능 (6.10.8.3 참조)을 사용할 수 있습니다. 예를 들면 다음과 같습니다.

#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */
    /* ... */
    fesetround(FE_UPWARD);
    /* ... */
#endif

4) 이는 적합한 구현이이 국제 표준에 명시 적으로 예약 된 식별자 이외의 식별자를 보유하지 않음을 의미합니다.

5) 엄격하게 적합한 프로그램은 적합한 구현 중에서 최대한 이식성을 갖도록 고안되었습니다. 적합한 프로그램은 적합한 구현의 이식 불가능한 기능에 따라 달라질 수 있습니다.

실제로 모든 기능을 정의하는 독립형 환경에 필요한 유일한 헤더는 다음과 같습니다. <stdarg.h> (단지 매크로 일 수도 있고 종종 매크로 일 수도 있음 .

표준 C ++ — 독립형 환경

C 표준이 호스팅 환경과 독립 환경을 모두 인식하는 것처럼 C ++ 표준도 인식합니다. (ISO / IEC 14882 : 2011의 인용문)

1.4 구현 준수 [intro.compliance]

¶7 두 가지 종류의 구현이 정의되어있다 : 호스팅 구현독립 구현 . 호스팅 된 구현의 경우이 국제 표준은 사용 가능한 라이브러리 세트를 정의합니다. 독립 실행 형 구현은 운영 체제의 이점없이 실행할 수 있으며 특정 언어 지원 라이브러리 (17.6.1.3)를 포함하는 구현 정의 라이브러리 세트를 가지고 있습니다.

¶8 적합한 구현은 올바른 형식의 프로그램의 동작을 변경하지 않는 한 확장 기능 (추가 라이브러리 기능 포함)을 가질 수 있습니다. 이 국제 표준에 따라 잘못된 확장을 사용하는 프로그램을 진단하려면 구현이 필요합니다. 그러나 그렇게하면 그러한 프로그램을 컴파일하고 실행할 수 있습니다.

¶9 각 구현은 지원하지 않는 모든 조건부 지원 구성을 식별하고 모든 로케일 특정 특성을 정의하는 문서를 포함해야합니다.

3) 이 문서는 또한 구현 정의 동작을 정의합니다. 1.9 참조

17.6.1.3 독립 실행 형 구현 [규정 준수]

호스팅 및 독립 실행 형 (1.4)의 두 가지 구현이 정의됩니다. 호스팅 된 구현의 경우이 국제 표준은 사용 가능한 헤더 세트를 설명합니다.

독립 구현에는 구현 정의 헤더 세트가 있습니다. 이 세트는 최소한 표 16에 표시된 헤더를 포함해야한다.

헤더 제공된 버전 <cstdlib>을 선언한다 적어도 함수 abort, atexit, at_quick_exit, exit, 및 quick_exit(18.5). 이 표에 나열된 다른 헤더는 호스팅 된 구현과 동일한 요구 사항을 충족해야합니다.

표 16 — 독립형 구현을위한 C ++ 헤더

Subclause                           Header(s)
                                    <ciso646>
18.2  Types                         <cstddef>
18.3  Implementation properties     <cfloat> <limits> <climits>
18.4  Integer types                 <cstdint>
18.5  Start and termination         <cstdlib>
18.6  Dynamic memory management     <new>
18.7  Type identification           <typeinfo>
18.8  Exception handling            <exception>
18.9  Initializer lists             <initializer_list>
18.10 Other runtime support         <cstdalign> <cstdarg> <cstdbool>
20.9  Type traits                   <type_traits>
29    Atomics                       <atomic>

int main()C에서 사용하는 것은 어떻습니까?

C11 표준 쇼의 표준 §5.1.2.2.1 선호하는 표기법 -  int main(void)-하지만 보여 표준의 두 예제도 있습니다 int main(): §6.5.3.4 ¶8§6.7.6.3 ¶20 . 이제 예제는 '규범 적'이 아니라는 점에 유의해야합니다. 그들은 단지 예시 일 뿐이다. 예제에 버그가 있으면 표준 본문에 직접 영향을 미치지 않습니다. 즉, 예상되는 동작을 강력하게 나타내므로 표준 int main()에 예제가 포함 되어 int main()있으면 선호 표기법이 아니더라도 금지되지 않는 것이 좋습니다.

6.5.3.4 sizeof_Alignof연산자

¶8 예 3이 예에서, 가변 길이 배열의 크기는 계산되어 함수에서 반환됩니다.

#include <stddef.h>

size_t fsize3(int n)
{
    char b[n+3]; // variable length array
    return sizeof b; // execution time sizeof
}
int main()
{
    size_t size;
    size = fsize3(10); // fsize3 returns 13
    return 0;
}

@DavidBowling : 함수 정의 int main(){ … }는 함수가 인수를받지 않지만 AFAICT 함수 프로토 타입을 제공하지 않음을 지정합니다. 들어 main()그 문제는 거의 없다; 에 대한 재귀 호출이 있으면 main()인수가 확인되지 않습니다. 다른 함수의 경우 문제가 더 많습니다. 인수가 올바른지 확인하기 위해 함수를 호출 할 때 실제로 범위 내에 프로토 타입이 필요합니다.
Jonathan Leffler

1
@DavidBowling : 일반적으로 main()IOCCC와 같은 곳 외부에서는 재귀 적 으로 호출하지 않습니다 . 나는 주로 참신을위한 테스트 프로그램을 가지고있다. 당신이있는 경우 int i = 0; int main() { if (i++ < 10) main(i, i * i); return 0; }와 GCC로 컴파일 및 포함되지 않습니다 -Wstrict-prototypes, 그것은 엄격한 경고에서 깨끗하게 컴파일합니다. 이 경우 main(void)컴파일에 실패합니다.
Jonathan Leffler

61

나는 또는 main()중 하나를 반환해야 한다고 생각합니다 . 그들은에 정의되어 있습니다EXIT_SUCCESSEXIT_FAILUREstdlib.h


20
0도 표준입니다.
Chris Young

2
@ChrisYoung가 EXIT_SUCCESSEXIT_FAILURE일부 역사적인 운영 체제 때문에 (VMS는?) 나타낸다 성공에 0이 아닌 다른 번호를 사용했다. 요즘 어디에나 0입니다.
fuz

5
@ FUZxxl 당신은 정확하지만 내 의견과 충돌하지 않습니다. EXIT_SUCCESS는 실제로 0이 아닐 수 있지만 표준 (C89, C99, C11)은 모두 0 (및 EXIT_SUCCESS)을 상태 정의 종료의 구현 정의 형식으로 정의합니다.
Chris Young

2
@FUZxxl : VMS가 홀수 값 (예 : 1)을 사용하여 성공을 나타내고 짝수 값 (예 : 0)을 사용하여 실패를 나타냅니다. 불행하게도, 원래 ANSI C 표준은 EXIT_SUCCESS가 0이어야한다는 것을 의미하는 것으로 해석되었으므로 main에서 EXIT_SUCCESS를 반환하면 VMS에서 정확히 잘못된 동작이 발생합니다. VMS를위한 휴대용 작업은 exit(EXIT_SUCCESS)항상 옳은 일을하는 것입니다.
Adrian McCarthy

1
5.1.2.2.3 "주 함수의 반환 유형이 int와 호환되는 유형 인 경우, 초기 함수에서 주 함수로의 반환은 주 함수에 의해 반환 된 값을 인수로 사용하여 종료 함수를 호출하는 것과 같습니다. 11) 주 함수를 종료하는}에 도달하면 값 0을 리턴합니다. "
Lundin

38

C 및 C ++ 표준은 독립형 및 호스팅의 두 가지 구현 유형을 정의합니다.

  • C90 호스팅 환경

    허용되는 양식 1 :

    int main (void)
    int main (int argc, char *argv[])
    
    main (void)
    main (int argc, char *argv[])
    /*... etc, similar forms with implicit int */

    코멘트:

    앞의 두 개는 허용 된 형식으로 명시 적으로 언급되어 있으며, C90은 리턴 유형 및 함수 매개 변수에 "implicit int"를 허용했기 때문에 다른 것은 내재적으로 허용됩니다. 다른 형식은 허용되지 않습니다.

  • C90 독립형 환경

    main의 모든 형식 또는 이름이 허용됩니다 2 .

  • C99 호스팅 환경

    허용되는 양식 3 :

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */

    코멘트:

    C99가 "implicit int"를 제거 했으므로 main()더 이상 유효하지 않습니다.

    "또는 다른 구현 정의 방식으로"이상한, 모호한 문장이 소개되었습니다. 이는 " int main()다양한 매개 변수 "또는 "main이 구현 정의 형식을 가질 수 있음" 으로 해석 될 수 있습니다.

    일부 컴파일러는 후자의 방식으로 표준을 해석하기로 선택했습니다. 의심 할 여지없이, 표준 자체가 모호하기 때문에 표준 자체를 인용하여 엄격하게 준수하지 않는다고 쉽게 말할 수는 없습니다.

    그러나 완전히 거친 형태를 허용한다는 main()것은 아마도이 새로운 문장의 의도가 아니었을 것입니다. C99의 이론적 근거 (규범이 아님)는 문장이 int main 4에 대한 추가 매개 변수를 나타냅니다 .

    그러나 호스트 된 환경 프로그램 종료 섹션은 main이 int 5를 반환하지 않는 경우에 대해 논쟁을 계속합니다 . 이 섹션은 main을 선언하는 방법에 대한 규범은 아니지만 호스트 시스템에서도 main이 완전히 구현 정의 된 방식으로 선언 될 수 있음을 의미합니다.

  • C99 독립형 환경

    main의 모든 형식 또는 이름이 허용됩니다 6 .

  • C11 호스팅 환경

    허용 된 양식 7 :

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */
  • C11 독립형 환경

    main의 모든 형식 또는 이름이 허용됩니다 8 .


참고 int main()위의 버전 중에서 C의 호스팅 구현을위한 유효한 형태로 나열되지 않았다. C에서, C는 달리 ++, ()그리고 (void)다른 의미를 가지고있다. 전자는 언어에서 제거 될 수있는 더 이상 사용되지 않는 기능입니다. C11 향후 언어 지시 사항 참조 :

6.11.6 함수 선언자

빈 괄호 (프로토 타입 형식 매개 변수 유형 선언자가 아님)와 함께 함수 선언자를 사용하는 것은 더 이상 사용되지 않는 기능입니다.


  • C ++ 03 호스팅 환경

    허용되는 양식 9 :

    int main ()
    int main (int argc, char *argv[])

    코멘트:

    첫 번째 양식의 빈 괄호에 유의하십시오. 이 경우 C ++과 C는 다릅니다. C ++에서는 함수가 매개 변수를 사용하지 않기 때문입니다. 그러나 C에서는 매개 변수를 사용할 수 있음을 의미합니다.

  • C ++ 03 독립 환경

    시작시 호출 된 함수의 이름은 구현 정의됩니다. 이름이 지정된 경우 main()명시된 양식 10을 따라야합니다 .

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
  • C ++ 11 호스팅 환경

    허용 된 양식 11 :

    int main ()
    int main (int argc, char *argv[])

    코멘트:

    표준의 텍스트가 변경되었지만 동일한 의미를 갖습니다.

  • C ++ 11 독립 환경

    시작시 호출 된 함수의 이름은 구현 정의됩니다. 이름이 지정된 경우 main()명시된 양식 12를 따라야합니다 .

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])

참고 문헌

  1. ANSI X3.159-1989 2.1.2.2 호스팅 환경. "프로그램 시작"

    프로그램 시작시 호출되는 기능의 이름은 main입니다. 구현은이 함수에 대한 프로토 타입을 선언하지 않습니다. 반환 유형은 int이며 매개 변수는 없습니다.

    int main(void) { /* ... */ } 

    또는 두 개의 매개 변수가 있습니다 (여기서는 argc 및 argv라고 함). 선언 된 함수에 로컬이기 때문에 어떤 이름이든 사용할 수 있습니다.

    int main(int argc, char *argv[]) { /* ... */ }
  2. ANSI X3.159-1989 2.1.2.1 독립 환경 :

    C 환경에서 운영 체제의 이점없이 C 프로그램이 실행될 수있는 독립 환경에서는 프로그램 시작시 호출되는 함수의 이름과 유형이 구현 정의됩니다.

  3. ISO 9899 : 1999 5.1.2.2 호스팅 환경-> 5.1.2.2.1 프로그램 시작

    프로그램 시작시 호출되는 기능의 이름은 main입니다. 구현은이 함수에 대한 프로토 타입을 선언하지 않습니다. 반환 유형은 int이며 매개 변수는 없습니다.

    int main(void) { /* ... */ } 

    또는 두 개의 매개 변수가 있습니다 (여기서는 argc 및 argv라고 함). 선언 된 함수에 로컬이기 때문에 어떤 이름이든 사용할 수 있습니다.

    int main(int argc, char *argv[]) { /* ... */ }

    또는 등가; 9) 또는 다른 구현 정의 방식으로.

  4. 국제 표준의 이론적 근거 — 프로그래밍 언어 — C, 개정판 5.10. 5.1.2.2 호스팅 환경-> 5.1.2.2.1 프로그램 시작

    main에 대한 인수의 동작과 exit, main 및 atexit의 상호 작용 (§7.20.4.2 참조)의 동작은 argv 문자열 표현과 main이 반환 한 값의 의미에서 원하지 않는 다양성을 억제하기 위해 체계화되었습니다.

    main에 대한 인수로 argc 및 argv를 지정하면 광범위한 사전 연습이 인식됩니다. argv [argc]는 목록의 끝 부분에 대한 중복 검사를 제공하고 일반적인 관행에 따라 널 포인터 여야합니다.

    main은 0 또는 2 개의 인수로 선언 할 수있는 유일한 함수입니다. (다른 함수의 인수 수는 호출과 정의 사이에 정확히 일치해야합니다.)이 특별한 경우는 프로그램이 프로그램 인수 문자열에 액세스하지 않을 때 인수를 main으로 남겨 두는 광범위한 관행을 단순히 인식합니다. 많은 구현들이 주요한 주장에 대해 두 가지 이상의 주장을지지하지만, 그러한 관행은 표준에 의해 축복 받거나 금지되지 않습니다. 세 개의 인수로 main을 정의하는 프로그램은 엄격하게 준수하지 않습니다 (§J.5.1 참조).

  5. ISO 9899 : 1999 5.1.2.2 호스팅 환경-> 5.1.2.2.3 프로그램 종료

    메인 함수의 리턴 타입 INT와 호환되는 형식이면, 주 기능에 초기 호출로부터의 복귀를 인수로서 메인 함수에 의해 리턴 된 값과 종료 함수 호출하는 것과; 도달) 11 }것을 종료 main 함수는 값 0을 리턴합니다. 리턴 유형이 int와 호환되지 않으면 호스트 환경으로 리턴 된 종료 상태는 지정되지 않습니다.

  6. ISO 9899 : 1999 5.1.2.1 독립형 환경

    C 환경에서 운영 체제의 이점없이 C 프로그램이 실행될 수있는 독립 환경에서는 프로그램 시작시 호출되는 함수의 이름과 유형이 구현 정의됩니다.

  7. ISO 9899 : 2011 5.1.2.2 호스팅 환경-> 5.1.2.2.1 프로그램 시작

    이 섹션은 위에서 인용 한 C99와 동일합니다.

  8. ISO 9899 : 1999 5.1.2.1 독립형 환경

    이 섹션은 위에서 인용 한 C99와 동일합니다.

  9. ISO 14882 : 2003 3.6.1 주요 기능

    구현이 주요 기능을 미리 정의해서는 안됩니다. 이 기능은 과부하되지 않아야한다. int 유형의 리턴 유형을 가져야하지만 그렇지 않으면 유형이 구현 정의됩니다. 모든 구현은 다음과 같은 기본 정의를 모두 허용해야합니다.

    int main() { /* ... */ }

    int main(int argc, char* argv[]) { /* ... */ }
  10. ISO 14882 : 2003 3.6.1 주요 기능

    주요 기능을 정의하기 위해 독립 환경의 프로그램이 필요한지 여부는 구현 정의입니다.

  11. ISO 14882 : 2011 3.6.1 주요 기능

    구현이 주요 기능을 미리 정의해서는 안됩니다. 이 기능은 과부하되지 않아야한다. int 유형의 리턴 유형을 가져야하지만 그렇지 않으면 유형이 구현 정의됩니다. 모든 구현은 두 가지를 모두 허용해야한다

    — int를 반환하는 () 함수

    — int를 반환하는 (int, char에 대한 포인터를 가리키는) 함수

    주 유형으로 (8.3.5).

  12. ISO 14882 : 2011 3.6.1 주요 기능

    이 섹션은 위에서 인용 한 C ++ 03과 동일합니다.


한 가지 질문 : C ++ 표준은 독립형 환경에서 시작 기능의 서명이 구현도 정의했음을 의미합니까? 예를 들어, 구현 될 수있는 시작 기능을 정의 할 수 : int my_startup_function ()또는 int my_startup_function (int argc, char *argv[])하지만, 예를 들어, 할 수 있습니다 : char my_startup_function (long argc, int *argv[])시작 함수로뿐만 아니라? 아니에요 또한 모호하지 않습니까?
Utku

@Utku 이름이 지정되어 있지 않은 main()한, 서명 된 서명을 사용해야하므로 서명을 가질 수 있습니다 . void my_startup_function ()자립형 시스템의 프로그램에서 돌아 오는 것이 이치에 맞지 않기 때문에 압도적으로 가장 일반적인 것이있을 것이라고 생각합니다 .
Lundin

1
내가 참조. 그러나 시작 기능에 이름과 서명을 사용할 수 있다면 다른 서명도 사용할 수 main있습니까? 현명한 질문은 아니지만 미안한 이유를 이해할 수 없다면 미안합니다.
Utku

@Utku C와 C ++는 서로 다릅니다. C ++이 이것을 시행하는 이유는 알 수 없으며 근거가 없습니다. 나는 주범 (말장난 의도)이 초기에 주가 int, 기간을 반환해야한다고 선언 한 Stroustrup 이라고 생각합니다. 처음 C ++ 버전을 만들었을 때, 그는 호스팅 시스템에만 사용 되었기 때문입니다. 연결된 게시물에서 Stroustrup은 여전히 독립 실행 형 구현의 존재에 대해 잘 모르는 것 같습니다.
Lundin

1
C11 표준 초안에서 주목할만한 점은 func()쓸모없는 것으로 간주 되더라도 초안 자체가 int main()자체 예제에서 사용 된다는 것 입니다.
Antti Haapala

29

성공하면 0을, 에러는 0이 아닌 값을 반환합니다. 이것은 UNIX 및 DOS 스크립팅에서 프로그램에서 발생한 일을 찾기 위해 사용하는 표준입니다.


8

main() C89 및 K & R C에서 지정되지 않은 반환 유형은 기본적으로 'int`입니다.

return 1? return 0?
  1. 에 return 문을 쓰지 않으면 int main()닫기 {는 기본적으로 0을 반환합니다.

  2. return 0또는 return 1부모 프로세스에 의해 수신됩니다. 쉘에서는 쉘 변수로 들어가고 프로그램을 실행하고 쉘을 사용하지 않고 해당 변수를 사용하지 않으면의 반환 값에 대해 걱정할 필요가 없습니다 main().

주 함수가 반환 한 것을 어떻게 얻을 수 있습니까?를 참조하십시오 . .

$ ./a.out
$ echo $?

이렇게 $?하면 반환 값의 최하위 바이트를받는 변수 라는 것을 알 수 있습니다.main() .

유닉스 및 DOS 스크립팅 return 0에서 성공시 0이 아닌 오류가 반환됩니다. 이것은 유닉스 및 DOS 스크립팅에서 프로그램에서 발생한 일을 파악하고 전체 흐름을 제어하는 ​​데 사용되는 표준입니다.


4
엄밀히 말하면 $?환경 변수는 아닙니다. 쉘 사전 정의 된 (또는 내장) 변수입니다. 차이점을 찾기는 어렵지만 env인수없이 실행 하면 환경이 인쇄되고 환경에 $?표시되지 않습니다.
Jonathan Leffler

1
주요 "종료"가 C90이 아닌 C ++ 및 C99에만있는 경우 자동으로 0을 반환합니다.
Kaz

오타 : "닫기 {"가되어야합니다 }. 그래서 이것을 작게 편집 할 수는 없습니다.
스펜서

7

int를 반환하더라도 일부 OS (Windows)는 반환 된 값을 단일 바이트 (0-255)로 자릅니다.


4
유닉스는 대부분의 다른 운영 체제와 마찬가지로 동일하게 작동합니다. VMS가 EXIT_SUCCESS 또는 EXIT_FAILURE 이외의 다른 것을 반환하면 문제가 발생한다는 놀라운 이상한 일을 알고 있습니다.
Leon Timmermans

2
MSDN의 차이점 : mscorlib를 통해보고 된 경우 종료 코드는 부호있는 32 비트 정수 입니다. 종료 코드를 자르는 C 런타임 라이브러리 에 결함이 있음을 의미합니다 .

그렇습니다. Windows에서는 32 비트 정수가 리턴되고로 변환됩니다 unsigned. 이것은 32 비트 정수를 가진 UNIX 시스템에서 동일합니다. 그러나 두 시스템 중 하나의 UNIX 스타일 쉘은 일반적으로 부호없는 8 비트 정수만 유지합니다.
John McFarlane

4

운영 체제에서 리턴 값을 사용하여 프로그램 종료 방법을 확인할 수 있습니다.

반환 값 0은 대개 대부분의 운영 체제 (어쨌든 생각할 수있는 운영 체제)에서 OK를 의미합니다.

프로세스를 직접 호출 할 때도 확인할 수 있으며 프로그램이 종료되고 올바르게 완료되었는지 확인할 수 있습니다.

그것은 단지 프로그래밍 규칙 이 아닙니다 .


질문에는 운영 체제가 있음을 나타내는 것이 없습니다. 독립형 시스템에서는 값을 반환해도 의미가 없습니다.
Lundin

3

의 반환 값은 main()프로그램이 어떻게 종료되었는지 보여줍니다. 반환 값이 zero0이면 값이 0이 아닌 값은 실행에 문제가 있음을 나타냅니다.


1
이것은 질문에 대한 답변이 아닌 주석입니다.
Lundin

2

나는 표준이 성공적인 반환이 OS 기반이기 때문에 main이 반환 값을 필요로하지 않는다는 인상을 받았다. 성공적인 반환 자체를 삽입하는 컴파일러.

그러나 나는 보통 0을 반환합니다.


C99 (및 C ++ 98)를 사용하면 main에서 return 문을 생략 할 수 있습니다. C89에서는 리턴 문을 생략 할 수 없습니다.
Jonathan Leffler

이것은 답변이 아닌 설명입니다.
Lundin

이것은 질문에 대한 답변을 제공하지 않습니다. 저자에게 비평을하거나 설명을 요청하려면 게시물 아래에 의견을 남겨주십시오.
Steve Lillis

6
@SteveLillis : 2008 년에 SO에는 의견 섹션이 없었습니다.
graham.reeds

2

0을 리턴하면 프로그램이 작업을 성공적으로 완료했음을 프로그래머에게 알려야합니다.


main()정상 신호 에서 1을 반환 하면 오류가 발생했습니다. 0 신호 성공을 반환합니다. 프로그램이 항상 실패하면 1은 괜찮지 만 최선의 방법은 아닙니다.
Jonathan Leffler

1
@JonathanLeffler : 반환의 의미 1로는 main구현 정의이다. 언어 정의 값은 0, EXIT_SUCCESS(종종으로 정의 됨 0) 및 EXIT_FAILURE입니다. OpenVMS에서 성공적인 종료를 return 1;나타냅니다 .
Keith Thompson

VMS는 내가 말한 의미 내에서 '정상적인'것이 아닙니다. '이상한 가치는 성공이다'와 같은 것이 아닌가? VMS에서 짝수 값이 실패 했습니까?
Jonathan Leffler

2

생략 return 0

C 또는 C ++ 프로그램이 main컴파일러 의 끝에 도달하면 0을 리턴하는 코드를 자동으로 생성하므로 return 0;, 끝에 명시 적으로 넣을 필요가 없습니다.main .

참고 : 이 제안을 할 때 거의 두 가지 유형의 주석 중 하나가 이어집니다. "그것을 몰랐습니다." 또는 "나쁜 조언이야!" 내 근거는 표준에서 명시 적으로 지원하는 컴파일러 동작에 의존하는 것이 안전하고 유용하다는 것입니다. C의 경우 C99 이후; ISO / IEC 9899 : 1999 섹션 5.1.2.2.3 참조 :

[...] main함수 의 초기 호출에서 exit리턴은 main함수가 인수로 리턴 한 값을 사용 하여 함수 를 호출하는 것과 같습니다 . 도달 }그 종료한다main 함수가 값 0이 반환됩니다.

C ++의 경우 1998 년 첫 번째 표준 이후 ISO / IEC 14882 : 1998 섹션 3.6.1 참조 :

리턴 문이 발생하지 않고 제어가 메인의 끝에 도달하면 리턴 0을 실행하는 효과가 있습니다.

그 이후로 두 표준의 모든 버전 (C99 및 C ++ 98)은 동일한 아이디어를 유지했습니다. 우리는 C ++에서 자동으로 생성 된 멤버 함수에 의존하며 함수 return;의 끝에 명시적인 명령문을 작성하는 사람은 거의 없습니다 void. 생략에 대한 이유는 "이상하게 보인다" 로 요약되는 것처럼 보인다 . 나처럼 C 표준으로의 변경에 대한 이론적 근거가 궁금하다면 이 질문을 읽으십시오 . 또한 1990 년대 초에 이것은 당시에 정의되지 않은 행동 (광범위하게 지원 되기는했지만)이기 때문에 "조잡한 관행"으로 간주되었다.

또한 C ++ 핵심 가이드 라인 에는 return 0;끝에 여러 개의 생략 main인스턴스가 포함되어 있으며 명시적인 반환이 기록 된 인스턴스는 없습니다. 이 문서에서이 특정 주제에 대한 구체적인 지침은 아직 없지만, 그것은 적어도 관행에 대한 암묵적 인 것 같습니다.

그래서 나는 그것을 생략하는 것을 옹호합니다. 어떤 경우에는 코드를 생략하는 코드가 발견되면 표준에서 명시 적으로 지원되고 코드의 의미를 알 수 있습니다.


2
나중의 표준이 아닌 C89 만 구현하는 컴파일러는 여전히 매우 일반적이며 (2017 년에 이것을 작성 함) 가까운 미래에 매우 일반적으로 남아 있기 때문에 이것은 나쁜 조언 입니다. 예를 들어, 마지막으로 C99를 구현 한 Microsoft 컴파일러 버전을 확인 하지 않았 으며 이것이 GCC가 아닌 임베디드 시스템 컴파일러에서도 여전히 일반적이라는 것을 이해하고 있습니다.
zwol

4
@zwol : 28 년이 지난 컴파일러를 사용하는 것 외에는 선택의 여지가없는 사람은 명시 적으로 포함할지 여부를 결정하는 것보다 더 많은 문제가있을 수 있습니다 return 0;. 그러나 그 시대의 많은 컴파일러는 return 0;이전에도 암시 적을 구현 했습니다. 표준화.
Edward

2
실제로, 나는 많은 임베디드 시스템 작업을하고 return 010 년 이상 암시 적 으로 지원하지 않는 컴파일러를 만나지 못했습니다 . 또한 최신 버전의 Microsoft C도 지원합니다 . 정보가 최신 정보가 아닐 수 있습니다.
Edward

2
나는 이것이 C에서 논란의 여지가 있음을 이해할 수있다 (@zwol 당). C ++에서이를 둘러싼 논쟁은 순수한 말이 아닙니다.
궤도에서 가벼움 레이스

2
@Edward 나는 논쟁이 존재하지 않는다고 말하지 않았고, 말도 안된다고 말했다 : P
Lightness Races in Orbit

1

반환 할 내용은 실행 파일로 수행하려는 작업에 따라 다릅니다. 예를 들어 명령 줄 셸과 함께 프로그램을 사용하는 경우 성공하면 0을, 실패하면 0이 아닌 값을 반환해야합니다. 그런 다음 코드 결과에 따라 조건부 처리를 사용하여 쉘에서 프로그램을 사용할 수 있습니다. 또한 해석에 따라 0이 아닌 값을 할당 할 수 있습니다 (예 : 중대한 오류의 경우 다른 프로그램 종료 지점이 다른 종료 값을 가진 프로그램을 종료 할 수 있음) 코드가 쉘과 함께 사용되지 않고 리턴 된 값이 아무 것도 방해하지 않으면 생략 될 수 있습니다. 개인적으로 서명을 사용합니다int main (void) { .. return 0; .. }


main ()의 형식은 구현에 의해 결정되며 컴파일러를 의미합니다. 컴파일러가 여러 양식을 지원하는 경우를 제외하고 프로그래머는 선택할 양식을 선택하지 않습니다.
Lundin

@Lundin 반환 유형은 구현에 의해 구현됩니다. 그러나 반환되는 값은 프로그래머가 결정합니다. C99 섹션 5.1.2.2.3에서는의 반환 유형 main이와 호환 가능 하다고 언급합니다 int. 따라서 반품 int은 문제가되지 않습니다. 다른 리턴 유형이 허용되지만이 경우 리턴 값을 갖는 환경 변수는 지정되지 않습니다. 그러나 프로그래머가 return 0;bash에서 분기를 만드는 데 사용될 수 있습니다.
phoxis

1

프로세스에서 정수를 반환하는 효율성과 관련하여 실제로 문제가있는 경우 해당 프로세스를 너무 많이 호출하여이 반환 값이 문제가되지 않도록해야합니다.

이 작업을 수행하는 경우 (프로세스를 너무 많이 호출) 각 호출에 특정 프로세스를 할당하지 않고 로직을 호출자 또는 DLL 파일에 직접 넣는 방법을 찾아야합니다. 다중 프로세스 할당은이 경우 관련 효율성 문제를 발생시킵니다.

구체적으로, 0을 반환하는 것이 1을 반환하는 것보다 더 효율적인지 아닌지를 알고 싶다면 경우에 따라 컴파일러에서 의존 할 수 있지만 일반적으로 동일한 소스 (로컬, 필드, 상수, 임베디드)에서 읽은 것으로 가정합니다. 코드, 함수 결과 등)에는 정확히 동일한 수의 클럭 사이클이 필요합니다.


1

다음은 리턴 코드 사용법에 대한 간단한 데모입니다.

Linux 터미널이 제공하는 다양한 도구를 사용하는 경우 프로세스가 완료된 후 오류 처리를 위해 리턴 코드를 사용할 수 있습니다. 다음 텍스트 파일 myfile이 있다고 가정하십시오.

grep의 작동 방식을 확인하기위한 몇 가지 예입니다.

grep 명령을 실행하면 프로세스가 작성됩니다. 일단 끝나고 ​​나면 깨지지 않고 0에서 255 사이의 코드를 반환합니다. 예를 들면 다음과 같습니다.

$ grep order myfile

당신이 할 경우

$ echo $?
$ 0

당신은 0을 얻을 것이다. 왜? 때문에 GREP은 일치하는 항목을 발견하고 성공과 종료에 대한 일반적인 값 종료 코드 0을 반환. 다시 확인하지만 텍스트 파일에없는 것과 일치하므로 일치하는 항목이 없습니다.

$ grep foo myfile
$ echo $?
$ 1

grep이 파일 "foo"와 토큰 "foo"를 일치시키는 데 실패했기 때문에 리턴 코드는 1입니다 (실패한 경우이지만 위에서 언급 한대로 선택할 수있는 값이 많습니다).

매우 기본적인 것이지만 오류 처리에 대한 아이디어를 제공해야하지만 이제 다음 bash 스크립트 (Linux 터미널에 간단히 입력하십시오) :

$ grep foo myfile
$ CHECK=$?
$ [ $CHECK -eq 0] && echo 'Match found'
$ [ $CHECK -ne 0] && echo 'No match was found'
$ No match was found

"foo"가 grep을 1로 리턴 한 후 두 번째 줄 이후에는 아무 것도 출력되지 않고 grep의 리턴 코드가 0인지 확인합니다. 두 번째 조건문은 CHECK으로 인해 true이므로 마지막 줄에 메시지를 표시합니다. == 1.

당신이 이것을 호출하고 있는지 그 프로세스를 볼 수 있듯이, 때로는 main ()의 반환 값에 의해 반환 된 것을 보는 것이 필수적입니다.


셸 스크립트에서는 if grep foo myfile; then echo 'Match found'; else echo 'No match was found'; fi반환 상태를 직접 테스트하여 사용 합니다. 보고 등을 위해 상태를 캡처하려면 할당을 사용합니다. if grep foo myfile; CHECK=$?; [ "$CHECK" = 0 ]; then echo 'Match found'; else echo 'No match was found'; fi세 줄을 사용 하거나 사용할 수 있습니다 . 당신은 또한 옵션을 사용할 수 있습니다 -s-qgrep나타나지 일치 또는 루틴이 오류 메시지 발생을 예방하기 위해. 그러나 이것은 종료 상태가 유용 할 수있는 핵심 사항 인 셸 축소입니다.
Jonathan Leffler

1

C 및 C ++에서 main () 함수를 정의하는 올바른 (가장 효율적인) 방법은 무엇입니까? int main () 또는 void main () — 그 이유는 무엇입니까?

"(가장 효율적)"이라는 단어는 질문을 바꾸지 않습니다. 독립 환경에 있지 않는 한 보편적으로 올바른 선언 방법 main()이 있으며 int를 반환하는 것과 같습니다.

main()C와 C ++에서 무엇이 반환 되어야 합니까?

그것은 게 아니에요 해야 main() 그것이 무엇을 반환 하지 main() 수익을. main()물론 다른 사람이 호출하는 기능입니다. 을 호출하는 코드를 제어 할 수 없습니다 main(). 따라서 main()호출자와 일치하도록 유형이 올바른 서명으로 선언해야 합니다. 당신은 단순히 문제에 대한 선택의 여지가 없습니다. C와 C + 표준에 의해 답이 이미 완벽하게 정의되어 있기 때문에 더 효율적이거나 덜 효율적인 것, 더 나쁘거나 나쁜 스타일 또는 이와 유사한 것을 스스로에게 묻지 않아도됩니다. 그냥 따라와

int main ()이면 1을 반환하거나 0을 반환합니까?

성공하면 0, 실패하면 0이 아닙니다. 다시 말하지만, 선택해야 할 것은 아닙니다. 준수해야 할 인터페이스에 의해 정의됩니다.

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