본문 바로가기

프로그래밍 언어/C++

C++의 main 함수에 대해

반응형

execution environment

C++ 프로그램이 구동되는 실행 환경을 C++ 스펙에서는 크게 OS의 subsystem 환경하에서 구동하는 hosted environment과 독자적으로 실행하는 freestanding environment으로 구분한다.

hosted environment 실행 환경 요구 사항이 freestanding environment 실행 환경 요구 사항을 포함한다.

따라서 C++ 스펙은 hosted environment 실행 환경 요구 사항 기준으로 설명하고, 일부 요구 사항을 무효화함으로써 freestanding environment 실행 환경 요구 사항을 완성한다.

hosted environment 실행 환경 요구 사항을 준수한 C++ 컴파일러를 hosted implementation 컴파일러라고 하고, freestanding environment 실행 환경 요구 사항을 준수한 컴파일러를 freestanding implementation이라 한다.

main function

hosted environment 실행 환경에서 global scope에 오직 하나의 main 함수만을 포함해야 한다. main function를 실행하는 thread를 main thread라고 한다. main 함수가 호출되기 전에 non-local static storage duration 객체의 생성자를 environment 환경에서 호출해야 하고, main 함수를 벗어나면 생성자가 호출된 static storage duration 객체의 소멸자를 environment 환경에서 호출해야 한다.

freestanding environment 실행 환경에서는 위에 언급한 요구 사항을 무효화한다. 즉 main 함수가 없어도 되고, static storage duration 객체의 생성자나 소멸자를 호출하지 않아도 좋다. 따라서 아래에 설명한 내용을 모두 무시해도 된다.

main function 스펙 요구 사항

main 함수의 type 이름은 C++ language linkage를 가져야 하고, main 함수의 반환 타입은 int 타입을 반환하도록 선언되어야 한다. main 함수 이름에 대한 linkage는 구현 컴파일러가 정의한다. main 함수는 inline, static, constexpr, consteval function 또는 deleted function으로 선언될 수 없고, linkage-specification 구문과 함께 선언될 수 없다.

global scope에 변수 main를 선언할 수 없고, named module에 main 함수를 attch하도록 선언할 수 없다. global scope에 function template main를 선언할 수 없다. C language linkage로 선언된 이름은 global scope로 변경되기 때문에, C language linkage를 갖는 main 함수를 namespace에 선언할 수 없다. 그 외의 경우, main 사용은 제약 사항이 없다.

그 외에 나머지 사항은 구현 컴파일러마다 다르게 구현될 수 있다.

컴파일러 구현 과정에서 정형화된 main 함수 유형

다음에 설명하는 내용은 컴파일러 구현 과정에서 나름대로 정형화된 main 함수의 형태일 뿐, 스펙에서 요구하는 구현 준수 사항이 아니다. 일반적으로 다음과 세부 구현 사항을 따라, 구현 컴파일러는 다음 형태의 main 함수를 허용한다.

int main(); 
// or
int main(int argc, char** argv);

2번째 유형에서 argc는 hosted environment 실행 환경에서 main 함수를 실행하기 위해 제공한 argument 갯수로 사용하는데, 실행 파일의 경로 정보 또는 ""를 첫 항목으로 포함하기 때문에 항상 1 이상의 값을 갖는다. 제공된 정보는 argv[0] ~ argv[argc-1]로 null-terminated multibyte string의 포인터를 얻어낼 수 있다. argv[argc]NULL를 반환해야 한다.
추가적인 정보는 argv 이후에 추가할 수 있다. 예를 들어 environment 환경 정보를 제공하곤 한다.

main 함수에서 벗어나기

현재 block를 벗어나지 않고 프로그램을 종료하면(예를 들어, std::exit(int) 함수를 호출하는 경우) automatic storage duration를 갖는 모든 객체는 소멸되지 않는다. static 또는 thread storage duration를 가진 객체의 소멸 과정에서 std::exit(int)를 호출하면, undefined behavior다. 그에 비해 main 함수 내부에서 return 구문으로 main 함수를 종료하면 automatic storage duration를 가진 객체의 소멸자는 정상적으로 호출되고, return 구문으로 반환한 값은 std::exit를 호출하는 과정에서 argument로 사용한다. 실제적으로 hosted implementation 컴파일러에게 요구한 구현 사항이다. main 함수를 return 구문없이 벗어나면 return 0; 구문을 실행한 효과와 같다.

microsoft visual c++ studio에서 hosted implementation 컴파일러 구현부를 확인해보면, 위에 언급 내용대로 구현되어 있다.

반응형