gcc attribute: cleanup
The cleanup attribute runs a function when a variable goes out of scope. This attribute can only be applied to auto function scope variables.
March 26, 2026
gcc attribute: cleanup
Reqruies
- Compiler: gcc 3.3.1 이상
systemd 프로젝트 코드를 보면 attribute 키워드를 많이 볼 수 있습니다.
그중에서도 자원 누수(resource leak)를 방지하고 안전하고 견고한 코드를 작성하는 데 큰 도움이 되는 cleanup 속성(attribute)에 대해 살펴보겠습니다.
cleanup 속성은 GCC 문서에서 다음과 같이 설명하고 있습니다.
cleanup usage
gcc/Common-Variable-AttributesDocThe cleanup attribute runs a function when the variable goes out of scope.
This attribute can only be applied to auto function scope variables; it may not be applied to parameters or variables with static storage duration.
The function must take one parameter, a pointer to a type compatible with the variable. The return value of the function (if any) is ignored.
If -fexceptions is enabled, then cleanup_function is run during the stack unwinding that happens during the processing of the exception. Note that the cleanup attribute does not allow the exception to be caught, only to perform an action. It is undefined what happens if cleanup_function does not return normally.
문서 내용 중 다음 문장이 가장 핵심적인 특징을 설명하고 있습니다.
The cleanup attribute runs a function when the variable goes out of scope
즉, 이 속성을 잘 활용하면 malloc/free나 open/close처럼 항상 쌍(pair)을 맞춰 지정해 주어야 하는 자원을 관리하기 매우 쉬워지며, 개발자의 실수로 인한 자원 누수(
leak)를 미연에 방지할 수 있습니다.Sample Source Code - usage.cc
check resultbash
어셈블리 코드를 보면 auto_function()을 호출하는 코드가 gcc에 의해 자동으로 추가된 것을 확인할 수 있습니다.
Assembly - x86_64 AT&T (Usage)bash
Practical uses of cleanup
앞서 언급한 특징을 살려, 파일 포인터의 스코프가 끝날 때 자동으로 fclose()를 호출해주는 코드를 작성해 볼 수 있습니다.
여기서 지정하는 함수는 변수 자체가 아닌 **변수가 가진 값의 참조(포인터)**를 매개변수로 받아야 하므로,
FILE *의 포인터인 FILE **를 인자로 받도록 래퍼(wrapper)를 정의해야 합니다.Sample Source Code - fclosec
Timing of cleanup function call
cleanup 속성에 의해 함수가 호출되는 타이밍이 중요합니다.
문서에서는 다음과 같이 설명합니다.
The cleanup attribute runs a function when the variable goes out of scope
위 설명이 맞는지 확인해 봅시다.
Sample Source Code - scope.cc
check resultbash
어셈블리 코드를 확인해 보면, 변수
p가 선언된 블록(스코프)이 끝나는 시점(printf가 호출되기 직전)에 freep()을 호출하는 코드가 GCC에 의해 자동으로 삽입된 것을 알 수 있습니다.Assembly - x86_64 AT&T (scope)bash
Be careful with timing
cleanup 속성은 매우 강력하지만, 변수가 소속된 스코프를 벗어나는 순간 즉시 함수가 호출된다는 라이프사이클(Lifecycle) 특성을 정확히 이해해야 합니다.자칫하면 다음과 같은 코드 실수가 발생할 수 있습니다.
Sample Source Code - scope_precautions.cc
check resultbash
위 코드에서 개발자의 원래 구상(의도)은 새로 할당된 메모리를 반환하는 것이었습니다. 그러나 new_buffer 함수가 종료되는 순간, 함수 내 지역 변수인
p가 스코프를 벗어나게 되어 설정해둔 freep()가 즉시 실행되어 버립니다.그 결과, 나중에
main 함수에서 전달받아 사용하는 value 포인터는 이미 해제된(freed) 메모리 영역을 가리키게 됩니다.이에 문자열을 복사하려고 접근하면
Use-After-Free가 발생하면서 위와 같이 Segmentation fault로 비정상 종료되는 것입니다.Conclusion
GCC의 cleanup 속성은 변수가 범위를 벗어날 때 (즉, 스코프 종료 시) 지정된 함수를 자동으로 호출하여 리소스를 정리해 주는 매우 유용한 기능입니다.
C++의 RAII(Resource Acquisition Is Initialization) 패턴과 유사한 효과를 제공하여, 복잡한 예외나 에러 처리 과정에서도 누락 없이 안전하게 자원을 해제할 수단이 되어줍니다.
결론적으로, 변수의 스코프(Scope)와 자원의 생명주기(Lifecycle)를 정확히 이해하고 상황에 맞춰 적절히 활용한다면 C 언어 환경에서도 자원 해제에 얽매이지 않는 구조적이고 안전한 코드를 작성할 수 있습니다.