Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C 언어의 __attribute__((constructor))와 __attribute__((destructor)) 문법 완벽 가이드

C 프로그래밍에서 main() 함수가 실행되기 전에 특정 작업을 수행하거나, main() 함수가 종료된 후 정리(cleanup) 작업을 처리해야 하는 경우가 있습니다. 예를 들어 로그 초기화, 리소스 할당, 환경 설정 같은 시작 작업이나, 메모리 해제, 파일 닫기 같은 마무리 작업이 대표적입니다.

이러한 기능은 GCC에서 제공하는 __attribute__() 확장 문법을 사용하여 손쉽게 구현할 수 있습니다. 함수에 constructor 속성을 지정하면 해당 함수가 main() 실행 이전에 호출되고, destructor 속성을 지정하면 main() 종료 이후에 호출됩니다.

기본 문법

GCC의 __attribute__() 메커니즘에는 다양한 옵션이 있으며, 그중 두 가지를 활용합니다.

  • __attribute__((constructor)): 프로그램이 시작될 때(즉, main() 호출 전) 지정된 함수를 자동으로 실행합니다.
  • __attribute__((destructor)): main() 함수가 완료된 후 프로그램이 종료되기 직전에 지정된 함수를 자동으로 실행합니다.

예제 코드

아래 예제는 main() 이전과 이후에 각각 실행되는 두 개의 함수를 선언하고 구현한 코드입니다.

#include <stdio.h>
void before_main() __attribute__((constructor));
void after_main() __attribute__((destructor));

void before_main() {
    printf("This is executed before main.\n");
}

void after_main() {
    printf("This is executed after main.");
}

main() {
    printf("Inside main\n");
}

실행 결과

This is executed before main.
Inside main
This is executed after main.

동작 원리 및 활용 팁

컴파일러는 constructor 속성이 부여된 함수들을 .init_array 섹션에 등록하고, destructor 속성이 부여된 함수들을 .fini_array 섹션에 등록합니다. 프로그램 로딩 시 C 런타임(startup 코드)이 main()을 호출하기 전에 init 배열의 함수들을 순서대로 실행하고, 프로그램 종료 시 fini 배열의 함수들을 호출합니다.

또한 우선순위(priority)를 지정할 수도 있습니다. 예를 들어 __attribute__((constructor(101)))처럼 괄호 안에 숫자를 넣으면, 숫자가 작을수록 먼저 실행됩니다. 이 기능은 라이브러리 초기화, 전역 리소스 설정, 디버깅용 로그 출력 등에 유용하게 활용됩니다.

단, 이 문법은 GCC 및 Clang 계열 컴파일러에서 지원하는 확장 기능이므로, 표준 C 이식성이 중요한 프로젝트에서는 사용 여부를 신중히 검토해야 합니다.