main() 함수 이전 또는 이후에 함수 호출하는 3 가지 방법
여러분이 정의한 함수를 main 함수 이전에 호출되도록 할 수 있다는 것을 알고 계신가요?
보통은 함수를 정의하면 main 내에서 호출해서 사용하므로 main 시작 이전 또는 이후에 어떤 함수를 호출한다는 것은 불가능한 것으로 알고 있을겁니다.
하지만, 이를 위해 3 가지 방법이나 이용할 수 있습니다.
(1) gcc 확장기능 이용 : __attibute__((constructor)), __attribute__((destructor))
gcc 는 main 이전의 함수호출 기능을 지원하기 위해 __attribute__((constructor)) 라는 구문을 사용할 수 있습니다.
#include <stdio.h> __attribute__((constructor)) void before_main(void) { printf("this is before mainn"); } int main() { printf("this is mainn"); }
위의 코드를 gcc aa.c 와 같이 컴파일한 후 실행하면 아래와 같이 신기하게도 before_main 함수가 main 함수 이전에 호출됨을 확인할 수 있습니다.
sh> ./a.out this is before main this is main
main 이후에 함수호출을 하고 싶을 때는 __attribute__((destructor)) 를 사용하면 됩니다. 사용법은 constructor 와 동일합니다.
(2) c++ 생성자와 소멸자의 이용
c++ 에서는 생성자를 이용하면 위에서와 같은 효과를 누릴 수 있습니다.
#include <stdio.h> void before_main(void) { printf("this is before main\n"); } class caller { public: caller() { before_main(); } # 생성자 }; caller global_var; # main 함수 이전에 global 객체 생성 int main() { printf("this is main\n"); }
caller 라는 객체를 global 로 생성하는데 이는 main 이전의 준비작업에 해당하므로, 생성자를 등록해두면 이 시점에서 호출이 되는 것입니다.
마찬가지로, 생성자 대신 소멸자를 등록해두면 main 함수 이후에도 함수를 호출할 수 있습니다.
#include <stdio.h> void before_main(void) { printf("this is before main\n"); } void after_main(void) { printf("this is after main\n"); } class caller { public: caller() { before_main(); } ~caller() { after_main(); } # 소멸자 }; caller global_var; int main() { printf("this is main\n"); }
(3) atexit 함수 이용
main 이전은 아니지만, ANSI C 의 atexit() 함수를 사용하면 main 이후 프로그램 종료 시 함수를 호출할 수 있습니다.
atexit 함수는 함수포인터(function pointer)를 인자로 받아서 프로그램 종료 시에 해당 함수를 수행하게 됩니다.
int atexit(void (*function)(void));
#include <stdio.h> #include <stdlib.h> void after_main(void) { printf("this is after mainn"); } int main() { printf("this is mainn"); atexit(after_main); }