gcc attribute: format, format_arg

The format attribute specifies that a function takes printf, scanf, strftime or strfmon style arguments which should be type-checked against a format string.
April 8, 2026

gcc attribute: format, format_arg

Reqruies
  • Compiler: gcc 2.8.0 later

Prior knowledge

GCC 컴파일 옵션 중 -Wformat을 사용하면 printfscanf처럼 가변 인자를 다루는 함수를 사용할 때 발생할 수 있는 인자 불일치 등의 실수를 Compile-time에 미리 체크할 수 있다는 큰 장점이 있습니다.
그렇다면 우리가 직접 작성한 함수에서도 -Wformat 옵션에 의한 타입 검사 기능을 활용할 수는 없을까요?
예를 들어 아래와 같은 코드를 작성했다고 가정해 보겠습니다.
sample source code - format
c
Compile with -Wformat
bash
위 코드는 report 함수에 전달된 포맷 스트링의 서식 지정자 개수와 가변 인자의 개수가 일치하지 않음에도 불구하고, 아무런 경고 없이 컴파일에 성공합니다.
우리가 만든 report() 함수에도 -Wformat 검사 기능을 지정하여 이런 실수를 방지하려면 어떻게 해야 할까요?

format attribute

GCC 문서를 자세히 살펴보면 format이라는 attribute를 찾을 수 있습니다.
format (archetype, string-index, first-to-check)
Doc

The format attribute specifies that a function takes printf, scanf, strftime or strfmon style arguments which should be type-checked against a format string.

결론부터 말씀드리면, 이 속성을 사용하면 우리가 정의한 어떤 함수에도 -Wformat 컴파일 타임 검사를 적용할 수 있습니다.

usage

이제 앞선 예제 코드에 attribute format을 추가하여 컴파일 타임에 감지 가능하도록 수정해 보겠습니다.
sample source code - format.c
c
이제 다시 컴파일을 시도해 보면 다음과 같이 경고가 발생합니다.
Compile with -Wformat
bash
직접 만든 report 함수에서도 -Wformat 옵션에 의해 문제가 정상적으로 감지되었습니다.
사용법은 매우 간단합니다.
  • archetype: printf, scanf, strftime 등을 지정할 수 있습니다. 타겟에 따라 glibc의 gnu_*나 MinGW의 ms_* 등이 사용되기도 합니다.
  • string-index: 컴파일러가 구문을 검사할 때 기준이 되는 포맷 스트링(format string) 매개변수의 위치를 지정합니다. 인덱스는 0이 아닌 1부터 시작한다는 점에 주의해야 합니다.
  • first-to-check: 포맷 스트링에 맞춰 타입과 개수를 검사할 첫 번째 가변 인자의 위치를 지정합니다.

variable argument list

vprintf처럼 가변 인자 리스트(...) 대신 va_list 타입의 인자를 받는 함수의 경우 전달받은 가변 인자의 타입이나 개수를 직접 검사할 수는 없으므로 first-to-check0으로 설정하면 컴파일러가 이에 맞게 동작합니다.
sample source code - format_vprintf.c
c
Compile with -Wformat
bash
이 경우 컴파일러는 포맷 스트링 자체의 구성 오류만 검사하게 됩니다.
즉, 전달된 가변 인자의 개수나 타입에 직접 접근할 수는 없으므로, 아래와 같이 서식 지정자와 가변 인자의 개수가 일치하지 않는 상황은 감지할 수 없습니다.
-Wformat-extra-args is not detected
c
strftime 역시 동일한 방식으로 first-to-check를 0으로 설정하여 사용합니다.
sample source code - strftime.c
c
Compile with -Wformat
bash

function declaration

함수 선언부에서도 다음과 같이 속성을 지정할 수 있습니다.
이 속성은 매우 오래된 기능으로, GCC 2.8.0 릴리스부터 이미 포함되어 있었습니다.
당시에는 printfscanf 두 가지 archetype만 지원했었습니다.
gcc 2.8.0 release - c-common.c
c
strftime 지원은 GCC 2.95에서 추가되었습니다.

format_arg

GCC 관련 소스 코드나 문서를 살펴보다 보면 format_arg라는 속성도 심심치 않게 발견할 수 있습니다.
이 속성은 포맷 스트링을 가공하여 새로운 포맷 스트링을 반환하는 함수에 지정합니다.
예를 들어, 원래의 포맷 스트링 앞에 특정 접두어(prefix)를 붙여주거나 번역된 포맷 스트링을 반환하는 함수를 만들 때 유용합니다.
sample source code - format_arg.c
c
Compile with -Wformat
bash

conclusion

개인적으로 -Wformat은 런타임에 심각한 오류(메모리 참조 에러, 세그멘테이션 폴트 등)로 이어질 수 있는 포맷 스트링 관련 버그들을 컴파일 단계에서 미리 확인해 주는 매우 유용하고 강력한 옵션이라고 생각합니다.
따라서 코드를 작성할 때 가능하면 -Werror=format을 사용하여 포맷 관련 경고를 컴파일 에러로 격상 처리하는 것을 권장합니다.
하지만 직접 함수를 정의할 때 이러한 속성 지정을 깜빡하는 경우가 많습니다. 이를 방지하기 위해 GCC는 -Wmissing-format-attribute라는 옵션도 제공합니다.
결론적으로, 포맷 스트링을 인자로 받는 함수를 작성할 때는 개발자의 실수를 줄이고 프로그램의 안정성을 높이기 위해 format attribute를 적극적으로 지정하시기 바랍니다.
Jooojub
System S/W engineer
Explore Tags
Series
    Recent Post
    © 2026. jooojub. All right reserved.