Programing

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

lottogame 2020. 10. 2. 21:26
반응형

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


올바른 (가장 효율적인)을 정의하는 방법은 무엇입니까 main()- C와 C ++의 기능 int main()또는 void main()- 이유는? 만약 int main()다음 return 1return 0?


이 질문에는 다음을 포함하여 여러 가지 중복 항목이 있습니다.

관련 :


의 반환 값 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()이 허용 되나 피해야합니다.


허용되는 답변은 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()다른 방법으로 선언 할 수 있지만 이로 인해 프로그램 구현이 정의되고 더 이상 엄격하게 준수되지 않습니다.

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

마지막으로, main()프로그램에서 호출 할 때 표준 관점에서 잘못된 것은 없습니다 .

ISO / IEC 9899 : 1999 (C99) :

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

  • int반환형는 생략 될 수 없다.
  • 에서 return 문을 생략 할 수 있습니다 main(). 수행하고 main()완료하면 암시 적 return 0.

표준 C — 호스팅 환경

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

5.1.2.2.1 프로그램 시작

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

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

또는 두 개의 매개 변수를 사용합니다 (여기에서 argc로 지칭됩니다. argv이름이 선언 된 함수에 로컬이기 때문에 모든 이름을 사용할 수 있음).

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

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

선언 된 경우 주 기능에 대한 매개 변수는 다음 제약 조건을 준수해야합니다.

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

10) 따라서으로 int정의 된 typedef 이름으로 대체 int되거나의 유형이 argv로 작성 될 수 있습니다 char **argv.

C99 또는 C11에서 프로그램 종료

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

5.1.2.2.3 프로그램 종료

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

11) 6.2.4에 따라 자동 저장 기간이 선언 된 객체의 수명은 main전자의 경우 종료됩니다.

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

C89 (따라서 Microsoft C)에서는 main()함수가 반환되지만 반환 값을 지정하지 않으면 어떤 일이 발생하는지에 대한 설명 이 없습니다. 따라서 정의되지 않은 동작이 발생합니다.

7.22.4.4 exit기능

¶5 마지막으로 제어권이 호스트 환경으로 반환됩니다. 의 값 status이 0 또는 EXIT_SUCCESS이면 종료 성공 상태의 구현 정의 형식 이 반환됩니다. 의 값이 status이면 종료 실패EXIT_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. —end note]

¶3 함수 main는 프로그램 내에서 사용되지 않습니다. 의 연결 (3.5) main은 구현에 따라 정의됩니다. [...]

¶5 main의 return 문은 main 함수를 떠나고 (자동 저장 기간이있는 모든 객체를 소멸) std::exit인수로 반환 값을 호출 하는 효과가 있습니다. 제어가 return 문을 만나지 않고 main 끝에 도달하면 그 효과는

return 0;

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

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

표준 C — 공통 확장

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

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

세 번째 인수는 문자열에 대한 포인터의 null로 끝나는 목록이며, 각각은 이름, 등호 및 값 (비어있을 수 있음)이있는 환경 변수입니다. 이것을 사용하지 않아도 ' extern char **environ;' 를 통해 환경에 들어갈 수 있습니다 . 오랫동안이를 선언 한 헤더가 없었지만 POSIX 2008 표준은 이제 <unistd.h>.

이것은 부록 J에 문서화 된 공통 확장으로 C 표준에 의해 인식됩니다.

J.5.1 환경 인수

¶1 호스트 된 환경에서, main 함수는 char *envp[]null로 끝나는 포인터 배열을 가리키는 세 번째 인자를받습니다 char. 2.2.1).

마이크로 소프트 C

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

main의 선언 구문은 다음과 같습니다.

 int main();

또는 선택적으로

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

또는 mainwmain함수를 반환 void(반환 값 없음) 으로 선언 할 수 있습니다 . 선언 main하거나 wmainvoid를 반환하는 경우 return 문을 사용하여 부모 프로세스 또는 운영 체제에 종료 코드를 반환 할 수 없습니다. main또는 wmain가로 선언 된 경우 종료 코드를 반환하려면 함수 void를 사용해야합니다 exit.

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

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

Microsoft 페이지에는 또한 wmain()넓은 문자열 등을 사용하는 몇 가지 다른 대안이 나열되어 있습니다.

이 페이지 의 Microsoft Visual Studio 2005 버전은 대안으로 나열되지 않습니다 . Microsoft Visual Studio 2008 이상의 버전 이 있습니다.void main()

표준 C — 독립 환경

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

5.1.2 실행 환경

두 가지 실행 환경이 정의됩니다 : 독립형 및 호스팅 됨. 두 경우 모두 실행 환경에서 지정된 C 함수를 호출하면 프로그램 시작이 발생합니다. 정적 저장 기간이있는 모든 개체는 프로그램 시작 전에 초기화 (초기 값으로 설정)되어야합니다. 그러한 초기화의 방식과 타이밍은 그렇지 않으면 지정되지 않습니다. 프로그램 종료는 실행 환경에 대한 제어를 반환합니다.

5.1.2.1 독립 환경

독립 환경 (운영 체제의 이점없이 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.30.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;
}

나는 그 생각 main()중 하나를 반환해야 EXIT_SUCCESS하거나 EXIT_FAILURE. 그들은stdlib.h


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이 반환 형식 및 함수 매개 변수에 대해 "암시 적 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()것은 아마도 (?)이 새로운 문장의 의도가 아닐 것입니다. 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 프로그램 실행이 발생할 수 있음)에서는 프로그램 시작시 호출되는 함수의 이름과 유형이 구현에 따라 정의됩니다.

  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에 대한 두 가지 이상의 주장을 지원하지만, 그러한 실행은 표준에 의해 축복되거나 금지되지 않습니다. 세 개의 인수로 main을 정의하는 프로그램은 엄격하게 준수하지 않습니다 (§J.5.1 참조).

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

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

  6. ISO 9899 : 1999 5.1.2.1 독립 환경

    독립 환경 (운영 체제의 이점없이 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 유형이어야하지만 그렇지 않은 경우 유형은 구현에서 정의됩니다. 모든 구현은 main에 대한 다음 정의를 모두 허용해야합니다.

    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과 동일합니다.


성공하면 0을 반환하고 오류에 대해서는 0이 아닙니다. 이것은 프로그램에 무슨 일이 일어 났는지 알아 내기 위해 UNIX와 DOS 스크립팅에서 사용하는 표준입니다.


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().

In Unix and DOS scripting, return 0 on success and non-zero for error are usually returned. This is the standard used by Unix and DOS scripting to find out what happened with your program and controlling the whole flow.


Keep in mind that,even though you're returning an int, some OSes (Windows) truncate the returned value to a single byte (0-255).


The return value can be used by the operating system to check how the program was closed.

Return value 0 usually means OK in most operating systems (the ones I can think of anyway).

It also can be checked when you call a process yourself, and see if the program exited and finished properly.

It's NOT just a programming convention.


The return value of main() shows how the program exited. If the return value is zero it means that the execution was successful while any non-zero value will represent that something went bad in the execution.


Omit return 0

When a C or C++ program reaches the end of main the compiler will automatically generate code to return 0, so there is no need to put return 0; explicitly at the end of main.

Note: when I make this suggestion, it's almost invariably followed by one of two kinds of comments: "I didn't know that." or "That's bad advice!" My rationale is that it's safe and useful to rely on compiler behavior explicitly supported by the standard. For C, since C99; see ISO/IEC 9899:1999 section 5.1.2.2.3:

[...] a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0.

For C++, since the first standard in 1998; see ISO/IEC 14882:1998 section 3.6.1:

If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;

All versions of both standards since then (C99 and C++98) have maintained the same idea. We rely on automatically generated member functions in C++, and few people write explicit return; statements at the end of a void function. Reasons against omitting seem to boil down to "it looks weird". If, like me, you're curious about the rationale for the change to the C standard read this question. Also note that in the early 1990s this was considered "sloppy practice" because it was undefined behavior (although widely supported) at the time.

Additionally, the C++ Core Guidelines contains multiple instances of omitting return 0; at the end of main and no instances in which an explicit return is written. Although there is not yet a specific guideline on this particular topic in that document, that seems at least a tacit endorsement of the practice.

So I advocate omitting it; others disagree (often vehemently!) In any case, if you encounter code that omits it, you'll know that it's explicitly supported by the standard and you'll know what it means.


I was under the impression that standard specifies that main doesn't need a return value as a successful return was OS based (zero in one could be either a success or a failure in another), therefore the absence of return was a cue for the compiler to insert the successful return itself.

However I usually return 0.


Returning 0 should tell the programmer that the program has successfully finished the job.


What to return depends on what you want to do with the executable. For example if you are using your program with a command line shell, then you need to return 0 for a success and a non zero for failure. Then you would be able to use the program in shells with conditional processing depending on the outcome of your code. Also you can assign any nonzero value as per your interpretation, for example for critical errors different program exit points could terminate a program with different exit values , and which is available to the calling shell which can decide what to do by inspecting the value returned. If the code is not intended for use with shells and the returned value does not bother anybody then it might be omitted. I personally use the signature int main (void) { .. return 0; .. }


If you really have issues related to efficiency of returning an integer from a process, you should probably avoid to call that process so many times that this return value becomes an issue.

If you are doing this (call a process so many times), you should find a way to put your logic directly inside the caller, or in a DLL file, without allocate a specific process for each call; the multiple process allocations bring you the relevant efficiency problem in this case.

In detail, if you only want to know if returning 0 is more or less efficient than returning 1, it could depend from the compiler in some cases, but generically, assuming they are read from the same source (local, field, constant, embedded in the code, function result, etc.) it requires exactly the same number of clock cycles.


What is the correct (most efficient) way to define the main() function in C and C++ — int main() or void main() — and why?

Those words "(most efficient)" don't change the question. Unless you're in a freestanding environment, there is one universally correct way to declare main(), and that's as returning int.

What should main() return in C and C++?

It's not what should main() return, it's what does main() return. main() is, of course, a function that someone else calls. You don't have any control over the code that calls main(). Therefore, you must declare main() with a type-correct signature to match its caller. You simply don't have any choice in the matter. You don't have to ask yourself what's more or less efficient, or what's better or worse style, or anything like that, because the answer is already perfectly well defined, for you, by the C and C+ standards. Just follow them.

If int main() then return 1 or return 0?

0 for success, nonzero for failure. Again, not something you need to (or get to) pick: it's defined by the interface you're supposed to be conforming to.


Here is a small demonstration of the usage of return codes...

When using the various tools that the Linux terminal provides one can use the return code for example for error handling after the process has been completed. Imagine that the following text file myfile is present:

This is some example in order to check how grep works.

When you execute the grep command a process is created. Once it is through (and didn't break) it returns some code between 0 and 255. For example:

$ grep order myfile

If you do

$ echo $?
$ 0

you will get a 0. Why? Because grep found a match and returned an exit code 0, which is the usual value for exiting with a success. Let's check it out again but with something that is not inside our text file and thus no match will be found:

$ grep foo myfile
$ echo $?
$ 1

Since grep failed to match the token "foo" with the content of our file the return code is 1 (this is the usual case when a failure occurs but as stated above you have plenty of values to choose from).

Now the following bash script (simply type it in a Linux terminal) although very basic should give some idea of error handling:

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

After the second line nothing is printed to the terminal since "foo" made grep return 1 and we check if the return code of grep was equal to 0. The second conditional statement echoes its message in the last line since it is true due to CHECK == 1.

As you can see if you are calling this and that process it is sometimes essential to see what it has returned (by the return value of main()).

참고URL : https://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c

반응형