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 컴파일러 구현부를 확인해보면, 위에 언급 내용대로 구현되어 있다.
'프로그래밍 언어 > C++' 카테고리의 다른 글
value category의 서로 다른 유형간 변환 (0) | 2024.02.05 |
---|---|
function과 value category 이해하기 (0) | 2024.02.02 |
value category 이해하는 첫 단추 (0) | 2024.02.01 |
range-based for 구문 이해하기 (1) | 2024.01.28 |
프로그램 종료 과정 이해하기 (1) | 2024.01.26 |