C 및 C ++에서 main ()은 무엇을 반환해야합니까?
올바른 (가장 효율적인)을 정의하는 방법은 무엇입니까 main()
- C와 C ++의 기능 int main()
또는 void main()
- 이유는? 그리고 논쟁은 어떻습니까? 만약 int main()
다음 return 1
나 return 0
?
이 질문에는 다음을 포함하여 여러 가지 중복 항목이 있습니다.
- C의 main()함수에 유효한 서명은 무엇입니까 ?
- main()함수 의 반환 유형
- 차이 void main()와 int main()?
- main()C ++에서의 서명
- 의 적절한 선언은 main()무엇입니까? — C ++의 경우 정말 좋은 대답입니다.
- main()C 의 함수 스타일
- main()C에서 메서드의 반환 유형
- int main()대 void main()C
관련 :
- C ++ — int main(int argc, char **argv)
- C ++ — int main(int argc, char *argv[])
- 인가 char *envp[]에 세 번째 인수로 main()휴대용?
- int main()함수가 모든 컴파일러에서 값을 반환 해야 합니까?
- main()C 및 C ++ 의 함수 유형은 사용자가 정의해야하는 이유는 무엇 입니까?
- 왜 int main(){}컴파일합니까?
- main()C ++ 14 의 법적 정의 ?
답변
의 반환 값 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)와 ISO / IEC 9899 : 1999 (C99) 간에도 일부 변경 사항이 있습니다.
main()
다음 중 하나로 선언되어야합니다.
int main(void)
int main(int argc, char **argv)
또는 동등합니다. 예를 들어 int main(int argc, char *argv[])
는 두 번째와 동일합니다. C90에서는 int
반환 형식이 기본값이므로 생략 할 수 있지만 C99 이상에서는 int
반환 형식을 생략 할 수 없습니다.
구현이 허용하는 경우 main()
다른 방법 (예 :)으로 선언 할 수 int main(int argc, char *argv[], char *envp[])
있지만 이로 인해 프로그램 구현이 정의되고 더 이상 엄격하게 준수되지 않습니다.
(즉, 구현 정의 된 동작에 의존하지 않음) 엄격하게 준수되는 반환에 대한 표준을 정의 3 개 값을 0
하고 EXIT_SUCCESS
성공적으로 종결하고, EXIT_FAILURE
실패 종료합니다. 다른 모든 값은 비표준이며 구현이 정의되어 있습니다. C90에서는 정의되지 않은 동작을 방지하기 위해 끝에 main()
명시적인 return
문 이 있어야합니다 . C99 이상에서는에서 return 문을 생략 할 수 있습니다 main()
. 수행하고 main()
완료하면 암시 적 return 0
.
마지막으로, C 프로그램에서 main()
재귀 적 으로 호출하는 표준 관점에서는 잘못된 것이 없습니다 .
표준 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]
은 프로그램 매개 변수 를 나타냅니다.- 배열이 가리키는 매개 변수
argc
및argv
및 문자열은argv
프로그램에 의해 수정 가능해야하며 프로그램 시작과 프로그램 종료 사이에 마지막으로 저장된 값을 유지해야합니다.10) 따라서으로
int
정의 된 typedef 이름으로 대체int
되거나의 유형이argv
으로 작성 될 수 있습니다char **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_FAILURE
및 EXIT_SUCCESS
from을 사용할 수 <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 표준에서 (위 인용)은 (따로 각주에서, 이는 단순히 문서 그 와 정의 에서 ).exit
EXIT_SUCCESS
EXIT_FAILURE
<cstdlib>
표준 C — 공통 확장
고전적으로 Unix 시스템은 세 번째 변형을 지원합니다.
int main(int argc, char **argv, char **envp) { ... }
세 번째 인수는 문자열에 대한 포인터의 null로 끝나는 목록으로, 각각은 이름, 등호 및 값 (비어있을 수 있음)이있는 환경 변수입니다. 이것을 사용하지 않아도 ' extern char **environ;
' 를 통해 환경에 들어갈 수 있습니다 . 이 전역 변수는 선언하는 헤더가 없다는 점에서 POSIX에서 고유합니다.
이것은 부록 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[]);
또는
main
및wmain
함수를 반환void
(반환 값 없음) 으로 선언 할 수 있습니다 . 선언main
하거나wmain
void를 반환하는 경우 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()
Standard C — Freestanding Environment
As noted early on, the requirements above apply to hosted environments. If you are working with a freestanding environment (which is the alternative to a hosted environment), then the standard has much less to say. For a freestanding environment, the function called at program startup need not be called main
and there are no constraints on its return type. The standard says:
5.1.2 Execution environments
Two execution environments are defined: freestanding and hosted. In both cases, program startup occurs when a designated C function is called by the execution environment. All objects with static storage duration shall be initialized (set to their initial values) before program startup. The manner and timing of such initialization are otherwise unspecified. Program termination returns control to the execution environment.
5.1.2.1 Freestanding environment
In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined. Any library facilities available to a freestanding program, other than the minimal set required by clause 4, are implementation-defined.
The effect of program termination in a freestanding environment is implementation-defined.
The cross-reference to clause 4 Conformance refers to this:
¶5 A strictly conforming program shall use only those features of the language and library specified in this International Standard.3) It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior, and shall not exceed any minimum implementation limit.
¶6 The two forms of conforming implementation are hosted and freestanding. A conforming hosted implementation shall accept any strictly conforming program. A conforming freestanding implementation shall accept any strictly conforming program in which the use of the features specified in the library clause (clause 7) is confined to the contents of the standard headers
<float.h>
,<iso646.h>
,<limits.h>
,<stdalign.h>
,<stdarg.h>
,<stdbool.h>
,<stddef.h>
,<stdint.h>
, and<stdnoreturn.h>
. A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program.4)¶7 A conforming program is one that is acceptable to a conforming implementation.5)
3) A strictly conforming program can use conditional features (see 6.10.8.3) provided the use is guarded by an appropriate conditional inclusion preprocessing directive using the related macro. For example:
#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */ /* ... */ fesetround(FE_UPWARD); /* ... */ #endif
4) This implies that a conforming implementation reserves no identifiers other than those explicitly reserved in this International Standard.
5) Strictly conforming programs are intended to be maximally portable among conforming implementations. Conforming programs may depend upon non-portable features of a conforming implementation.
It is noticeable that the only header required of a freestanding environment that actually defines any functions is <stdarg.h>
(and even those may be — and often are — just macros).
Standard C++ — Freestanding Environment
Just as the C standard recognizes both hosted and freestanding environment, so too does the C++ standard. (Quotes from ISO/IEC 14882:2011.)
1.4 Implementation compliance [intro.compliance]
¶7 Two kinds of implementations are defined: a hosted implementation and a freestanding implementation. For a hosted implementation, this International Standard defines the set of available libraries. A freestanding implementation is one in which execution may take place without the benefit of an operating system, and has an implementation-defined set of libraries that includes certain language-support libraries (17.6.1.3).
¶8 A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any well-formed program. Implementations are required to diagnose programs that use such extensions that are ill-formed according to this International Standard. Having done so, however, they can compile and execute such programs.
¶9 Each implementation shall include documentation that identifies all conditionally-supported constructs that it does not support and defines all locale-specific characteristics.3
3) This documentation also defines implementation-defined behavior; see 1.9.
17.6.1.3 Freestanding implementations [compliance]
Two kinds of implementations are defined: hosted and freestanding (1.4). For a hosted implementation, this International Standard describes the set of available headers.
A freestanding implementation has an implementation-defined set of headers. This set shall include at least the headers shown in Table 16.
The supplied version of the header
<cstdlib>
shall declare at least the functionsabort
,atexit
,at_quick_exit
,exit
, andquick_exit
(18.5). The other headers listed in this table shall meet the same requirements as for a hosted implementation.Table 16 — C++ headers for freestanding implementations
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>
What about using int main()
in C?
The standard §5.1.2.2.1 of the C11 standard shows the preferred notation — int main(void)
— but there are also two examples in the standard which show int main()
: §6.5.3.4 ¶8 and §6.7.6.3 ¶20. Now, it is important to note that examples are not 'normative'; they are only illustrative. If there are bugs in the examples, they do not directly affect the main text of the standard. That said, they are strongly indicative of expected behaviour, so if the standard includes int main()
in an example, it suggests that int main()
is not forbidden, even if it is not the preferred notation.
6.5.3.4 The
sizeof
and_Alignof
operators…
¶8 EXAMPLE 3 In this example, the size of a variable length array is computed and returned from a function:
#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; }
I believe that main()
should return either EXIT_SUCCESS
or EXIT_FAILURE
. They are defined in stdlib.h
Note that the C and C++ standards define two kinds of implementations: freestanding and hosted.
C90 hosted environment
Allowed forms 1:
int main (void) int main (int argc, char *argv[]) main (void) main (int argc, char *argv[]) /*... etc, similar forms with implicit int */
Comments:
The former two are explicitly stated as the allowed forms, the others are implicitly allowed because C90 allowed "implicit int" for return type and function parameters. No other form is allowed.
C90 freestanding environment
Any form or name of main is allowed 2.
C99 hosted environment
Allowed forms 3:
int main (void) int main (int argc, char *argv[]) /* or in some other implementation-defined manner. */
Comments:
C99 removed "implicit int" so
main()
is no longer valid.A strange, ambiguous sentence "or in some other implementation-defined manner" has been introduced. This can either be interpreted as "the parameters to
int main()
may vary" or as "main can have any implementation-defined form".Some compilers have chosen to interpret the standard in the latter way. Arguably, one cannot easily state that they are not strictly conforming by citing the standard in itself, since it is is ambiguous.
However, to allow completely wild forms of
main()
was probably(?) not the intention of this new sentence. The C99 rationale (not normative) implies that the sentence refers to additional parameters toint main
4.Yet the section for hosted environment program termination then goes on arguing about the case where main does not return int 5. Although that section is not normative for how main should be declared, it definitely implies that main might be declared in a completely implementation-defined way even on hosted systems.
C99 freestanding environment
Any form or name of main is allowed 6.
C11 hosted environment
Allowed forms 7:
int main (void) int main (int argc, char *argv[]) /* or in some other implementation-defined manner. */
C11 freestanding environment
Any form or name of main is allowed 8.
Note that int main()
was never listed as a valid form for any hosted implementation of C in any of the above versions. In C, unlike C++, ()
and (void)
have different meanings. The former is an obsolescent feature which may be removed from the language. See C11 future language directions:
6.11.6 Function declarators
The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature.
C++03 hosted environment
Allowed forms 9:
int main () int main (int argc, char *argv[])
Comments:
Note the empty parenthesis in the first form. C++ and C are different in this case, because in C++ this means that the function takes no parameters. But in C it means that it may take any parameter.
C++03 freestanding environment
The name of the function called at startup is implementation-defined. If it is named
main()
it must follow the stated forms 10:// implementation-defined name, or int main () int main (int argc, char *argv[])
C++11 hosted environment
Allowed forms 11:
int main () int main (int argc, char *argv[])
Comments:
The text of the standard has been changed but it has the same meaning.
C++11 freestanding environment
The name of the function called at startup is implementation-defined. If it is named
main()
it must follow the stated forms 12:// implementation-defined name, or int main () int main (int argc, char *argv[])
References
ANSI X3.159-1989 2.1.2.2 Hosted environment. "Program startup"
The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
ANSI X3.159-1989 2.1.2.1 Freestanding environment:
In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined.
ISO 9899:1999 5.1.2.2 Hosted environment -> 5.1.2.2.1 Program startup
The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;9) or in some other implementation-defined manner.
Rationale for International Standard — Programming Languages — C, Revision 5.10. 5.1.2.2 Hosted environment --> 5.1.2.2.1 Program startup
The behavior of the arguments to main, and of the interaction of exit, main and atexit (see §7.20.4.2) has been codified to curb some unwanted variety in the representation of argv strings, and in the meaning of values returned by main.
The specification of argc and argv as arguments to main recognizes extensive prior practice. argv[argc] is required to be a null pointer to provide a redundant check for the end of the list, also on the basis of common practice.
main is the only function that may portably be declared either with zero or two arguments. (The number of other functions’ arguments must match exactly between invocation and definition.) This special case simply recognizes the widespread practice of leaving off the arguments to main when the program does not access the program argument strings. While many implementations support more than two arguments to main, such practice is neither blessed nor forbidden by the Standard; a program that defines main with three arguments is not strictly conforming (see §J.5.1.).
ISO 9899:1999 5.1.2.2 Hosted environment --> 5.1.2.2.3 Program termination
If the return type of the main function is a type compatible with int, 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;11) reaching the
}
that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.ISO 9899:1999 5.1.2.1 Freestanding environment
In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined.
ISO 9899:2011 5.1.2.2 Hosted environment -> 5.1.2.2.1 Program startup
This section is identical to the C99 one cited above.
ISO 9899:1999 5.1.2.1 Freestanding environment
This section is identical to the C99 one cited above.
ISO 14882:2003 3.6.1 Main function
An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both of the following definitions of main:
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
ISO 14882:2003 3.6.1 Main function
It is implementation-defined whether a program in a freestanding environment is required to define a main function.
ISO 14882:2011 3.6.1 Main function
An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both
— a function of () returning int and
— a function of (int, pointer to pointer to char) returning int
as the type of main (8.3.5).
ISO 14882:2011 3.6.1 Main function
This section is identical to the C++03 one cited above.
Return 0 on success and non-zero for error. This is the standard used by UNIX and DOS scripting to find out what happened with your program.
main()
in C89 and K&R C unspecified return types default to ’int`.
return 1? return 0?
If you do not write a return statement in
int main()
, the closing{
will return 0 by default.return 0
orreturn 1
will be received by the parent process. In a shell it goes into a shell variable, and if you are running your program form a shell and not using that variable then you need not worry about the return value ofmain()
.
See How can I get what my main function has returned?.
$ ./a.out $ echo $?
This way you can see that it is the variable $?
which receives the least significant byte of the return value of 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.
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.
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 theexit
function with the value returned by themain
function as its argument; reaching the}
that terminates themain
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.
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.
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()).
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.
In C, the Section 5.1.2.2.1 of the C11 standard (emphasis mine):
It shall be defined with a return type of
int
and with no parameters:int main(void) { /* ... */ }
or with two parameters (referred to here as
argc
andargv
, though any names may be used, as they are local to the function in which they are declared):int main(int argc, char *argv[]) { /* ... */ }
However for some beginners like me, an abstract example would allow me to get a grasp on it:
When you write a method in your program, e.g. int read_file(char filename[LEN]);
, then you want, as the caller of this method to know if everything went well (because failures can happen, e.g. file could not be found). By checking the return value of the method you can know if everything went well or not, it's a mechanism for the method to signal you about its successful execution (or not), and let the caller (you, e.g. in your main method) decide how to handle an unexpected failure.
So now imagine I write a C program for a micro-mechanism which is used in a more complex system. When the system calls the micro-mechanism, it wants to know if everything went as expected, so that it can handle any potential error. If the C program's main method would return void, then how would the calling-system know about the execution of its subsystem (the micro-mechanism)? It cannot, that's why main() returns int, in order to communicate to its caller a successful (or not) execution.
In other words:
The rational is that the host environment (i.e. Operating System (OS)) needs to know if the program finished correctly. Without an int-compatible type as a return type (eg. void), the "status returned to the host environment is unspecified" (i.e. undefined behavior on most OS).