main의 올바른 선언은 무엇입니까?


147

mainC ++ 에서 함수 의 올바른 서명은 무엇입니까 ? 올바른 반환 유형은 무엇이며 값을 반환한다는 것은 무엇을 의미 main합니까? 허용되는 매개 변수 유형은 무엇이며 의미는 무엇입니까?

이 시스템에만 해당됩니까? 시간이 지남에 따라 이러한 규칙이 변경 되었습니까? 위반하면 어떻게 되나요?


1
이것은 C 및 C ++로 반환 해야하는 내용main 과 매우 밀접한 관련이 있거나 복제본입니다 .
Jonathan Leffler

@JonathanLeffler No kidding ... 약 8 개월 전에 개정 6 의 사본 목록에 추가되었습니다 .
fredoverflow

답변:


192

main기능은 글로벌 네임 스페이스에 비 멤버 함수로 선언해야합니다. 이것은 클래스의 정적 또는 비 정적 멤버 함수가 될 수 없으며 네임 스페이스 (이름이없는 네임 스페이스)에도 배치 할 수 없음을 의미합니다.

이름 main은 전역 네임 스페이스의 함수를 제외하고 C ++에서 예약되지 않았습니다. main전역 네임 스페이스에없는 클래스, 변수, 열거 형, 멤버 함수 및 비 멤버 함수를 포함하여 이름이 지정된 다른 엔티티를 자유롭게 선언 할 수 있습니다 .

main멤버 함수 또는 네임 스페이스로 명명 된 함수를 선언 할 수 있지만 이러한 함수는 main프로그램이 시작되는 위치를 지정 하는 함수가 아닙니다 .

main함수는 다음과 같이 선언 할 수 없습니다 staticinline. 또한 오버로드 될 수 없습니다. main전역 네임 스페이스에 이름이 지정된 함수는 하나만있을 수 있습니다 .

main당신이 전화를 할 수 없습니다 : 기능은 프로그램에서 사용할 수없는 main코드에서 어디에서나 기능을 없으며 해당 주소를 취할 수 있습니다.

의 반환 유형은 main이어야합니다int . 다른 반환 유형은 허용되지 않는다 (잘못된 프로그램을보고 매우 일반적이기 때문에이 규칙은 굵게 표시되어 그 선언 main의 반환 유형 void, 이것은 아마도 관한 가장 많이 위반 한 규칙입니다 main기능).

두 가지 선언 main이 허용되어야합니다.

int main()               // (1)
int main(int, char*[])   // (2)

에서 (1) , 매개 변수가 없습니다.

에서는 2 개의 파라미터가 존재하고, 종래 명명 argc하고 argv각각. argv프로그램에 대한 인수를 나타내는 C 문자열 배열에 대한 포인터입니다. 배열 argc의 인수 수입니다 argv.

일반적으로 argv[0]프로그램 이름이 포함되어 있지만 항상 그런 것은 아닙니다. argv[argc]널 포인터가 보장됩니다.

배열 유형 인수 (예 char*[]:)는 실제로는 변장 포인터 유형 인수이므로 다음 두 가지 모두 쓸 수있는 유효한 방법 (2) 이며 둘 다 정확히 같은 것을 의미합니다.

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

일부 구현은 다른 유형과 개수의 매개 변수를 허용 할 수 있습니다. 지원 문서를 확인하려면 구현 설명서를 확인해야합니다.

main()성공을 나타내려면 0을, 실패를 나타내려면 0이 아닌 것으로 반환됩니다. 명시 적으로 return문장을 작성할 필요는 없습니다 main(): main()명시적인 return문장 없이 리턴 하면 , 마치 작성한 것과 같습니다 return 0;. 다음 두 main()기능은 동일한 동작을 갖습니다.

int main() { }
int main() { return 0; }

두 매크로가 있습니다 EXIT_SUCCESSEXIT_FAILURE정의, <cstdlib>그도에서 반환 할 수 있습니다 main()각각 성공과 실패를 나타 내기 위해이.

로 반환 된 값 main()exit()함수 로 전달되어 프로그램을 종료합니다.

이 모든 것은 호스팅 된 환경 (비공식적으로 전체 표준 라이브러리가 있고 프로그램을 실행하는 OS가있는 환경)을 위해 컴파일 할 때만 적용됩니다. 독립형 환경 (예 : 일부 유형의 임베디드 시스템)을 위해 C ++ 프로그램을 컴파일 할 수도 있습니다.이 경우 시작 및 종료가 전체적으로 정의되어 있으며 main()기능이 필요하지 않을 수도 있습니다. 최신 데스크톱 OS를 위해 C ++를 작성하는 경우 호스팅 환경을 위해 컴파일하는 것입니다.


1
IIRC에서 유일하게 보장 된 반환 값은 0, EXIT_SUCCESS (0과 동일) 및 EXIT_FAILURE입니다. 편집 : 아, 좋아, 0이 아닌 다른 상태 값이 반환 될 수 있지만 구현 정의 된 의미가 있습니다. EXIT_FAILURE만이 어떤 방식 으로든 실패 값으로 해석되도록 보장됩니다.
데릭 터크

4
@Synetech : 첫 번째 문장에서 "C ++에서 주 함수의 올바른 서명은 무엇입니까?" 질문에는 [c ++]와 [c ++-faq] 모두 태그가 붙어 있습니다. Java 또는 C # 사용자 (또는 다른 사람)가 여전히 혼란 스럽다면 도울 수 없습니다. C #에는 Main비 멤버 함수가 없으므로 정적 멤버 함수 여야합니다. 심지어 C89도 main돌아와야 int합니다. 나는 정확한 규칙을 알기 위해 K & R C에 충분히 익숙하지 않지만 K & R에서 리턴 유형이 다소 일반적이고 유형 = 암시 적이 지 않기 때문에 main리턴 해야 할 것으로 추측합니다 . intmainint
James McNellis

3
@Suhail : 언어 표준에 따르면 반환 유형은이라고합니다 int.
James McNellis

1
@Suhail : 그렇습니다. 코드가 올바른 C ++이 아니며 많은 컴파일러가 코드를 거부합니다.
James McNellis

2
@Suhail : Visual C ++에서는 void반환 형식 을 언어 확장으로 허용합니다 . 이를 허용하지 않는 컴파일러에는 GCC 및 Comeau가 포함됩니다.
James McNellis 2016 년

15

표준 문서, 3.6.1.2 주요 기능 ,

int 유형의 리턴 유형을 가져야하지만 그렇지 않으면 유형이 구현 정의됩니다. 모든 구현은 다음 main 정의를 모두 허용해야합니다.

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

후자의 형식 은 프로그램 이 실행되는 환경에서 프로그램에 전달 된 인수argc수입니다. argc가 0 아닌 경우이 인수는 argv [0]에서 argv [argc-1]로 초기에 대한 포인터로 제공됩니다. 널 종료 멀티 바이트 문자열의 문자 .....

도움이 되길 바랍니다 ..


2
의 반환 유형이 main되어야 하는 특정 이유 가 int있습니까?
Suhail Gupta 2016 년

1
@ SuhailGupta : 호출 프로세스는 프로세스가 성공적인 것으로 간주 되는지 여부를 알 수 있습니다. 허용하면 void해당 모델이 중단됩니다. "항상 성공으로 간주된다"는 말이 있다면 의미가 없습니다. 이 과정이 실제로 실패하면 말하는 방법이 없었 때문에, 그래서 당신은 않았다 정말 성공? 아니요,을 반환하십시오 int.
궤도에서 가벼움 경주

4

최신 출판 표준 (C ++ 14)의 정확한 표현은 다음과 같습니다.

구현은 두 가지를 모두 허용해야한다

  • 함수의 ()복귀 int

  • 의 함수 (int에 대한 포인터에 대한 포인터를 char)반환int

유형으로 main.

따라서 type의 main유형이 int()또는 이면 대체 철자가 허용됩니다 int(int, char**). 따라서 다음도 허용됩니다.

  • int main(void)
  • auto main() -> int
  • int main ( )
  • signed int main()
  • typedef char **a; typedef int b, e; e main(b d, a c)

1
NB. 나는이 답변을 다른 스레드에 대한 의견과 같이 게시했으며 누군가 누군가이 스레드를 int main(void)C ++에서 올바르지 않은 증거로 인용하려고했습니다 .
MM

3
@Stargateur auto main() -> int에는 추론 된 반환 유형이 없습니다. "(auto main () {... is not allowed)"에서 {에주의를 기울이고 아직 의미있는 것을 추가 할만큼 충분히 알지 못하는 경우 알아 두십시오.

3

두 개의 유효한 주 전원은 int main()int main(int, char*[])입니다. 다른 것은 컴파일되거나 컴파일되지 않을 수 있습니다. 경우 main명시 적으로 값을 반환하지 않습니다, 0은 암시 적으로 반환됩니다.


1
반환 유형 main이 void라고 언급 할 때 코드가 컴파일되지 않는 것을 본 적이 없습니다 . main의 반환 유형이 int이어야하는 특별한 이유가 있습니까?
Suhail Gupta 2016 년

4
언어 사양에 따르면 main은 반환 유형이 int 여야합니다. 컴파일러가 허용하는 다른 반환 유형은 컴파일러마다 개선 된 기능입니다. 기본적으로 void를 사용한다는 것은 C ++과 유사하지만 C ++과는 다른 언어로 프로그래밍하고 있음을 의미합니다.
stonemetal

2
표준이 int리턴 유형으로를 요구하는 이유는 main이 값이 프로그램의 종료 코드로 쉘에 전달되고을 sh기대하기 때문 int입니다.
uckelman

아마도 그 이유는 징계입니까? 둘 이상의 경로가있을 수 있습니다. 리턴 유형이 void모두 자동입니다. 를 통해 int에서 각 수익에 대한 특정 이탈 값을 정의해야합니다 main.
Andreas Spindler

2

반환 값 및 의미에 대한 세부 사항

3.6.1 ( [basic.start.main]) 당 :

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

return 0;

동작은 std::exit섹션 18.5 ( [support.start.term])에 자세히 설명되어 있으며 상태 코드를 설명합니다.

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

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