gcc attribute: nonnull

The nonnull attribute specifies that some function parameters should be non-null pointers. This allows the compiler to check at compile-time if a null pointer is passed to these arguments.
April 1, 2026

gcc attribute: nonnull

Reqruies
  • Compiler: gcc 3.3 or later
nonnull 속성을 사용하면, 포인터 인자에 NULL을 전달해서는 안 되는 함수를 호출할 때 명시적으로 NULL 상수가 전달되는 것을 컴파일 타임에 감지할 수 있습니다.
단, 이 속성은 함수 호출 시 인자 자리에 NULL 상수를 명시적으로 작성한 경우에 주로 동작한다는 특징이 있습니다.
런타임에 동적으로 결정되거나 변수를 거쳐 우회하여 전달되는 NULL은 인지하지 못하는 한계가 있는데, 이 제약 사항에 대해서는 뒤에서 자세히 다루겠습니다.
이 속성은 컴파일 시 -Wnonnull 또는 -Werror=nonnull 옵션과 함께 사용할 때만 경고나 에러를 발생시킬 수 있습니다.
의도적으로 -Wno-nonnull 옵션을 사용한다면 nonnull 속성을 적용하더라도 컴파일러의 아무런 제지를 받지 않습니다.
nonnull은 GCC 3.3 릴리스에서 처음 도입되었으며, 현재 리눅스 커널이나 glibc 등 수많은 오픈 소스 프로젝트에서 빌드 타임 오류 방지를 위해 널리 활용되고 있습니다.

GCC 3.3 Changes

GCC 3.3 Changes
Doc

C/ObjC/C++ ... A new function attribute, nonnull, has been added which allows pointer arguments to functions to be specified as requiring a non-null value. The compiler currently uses this information to issue a warning when it detects a null value passed in such an argument slot.

GCC 문서에도 관련 내용이 상세히 안내되어 있습니다.

GCC Documentation

gcc/Common-Function-Attributes
Doc

nonnull (arg-index, …) The nonnull attribute specifies that some function parameters should be non-null pointers. For instance, the declaration: extern void *    my_memcpy (void *dest, const void *src, size_t len)    attribute((nonnull (1, 2))); causes the compiler to check that, in calls to my_memcpy, arguments dest and src are non-null. If the compiler determines that a null pointer is passed in an argument slot marked as non-null, and the -Wnonnull option is enabled, a warning is issued. The compiler may also choose to make optimizations based on the knowledge that certain function arguments will never be null. If no argument index list is given to the nonnull attribute, all pointer arguments are marked as non-null.

Usage

이 속성은 사용법이 매우 간단하여 샘플 코드를 통해 쉽게 이해할 수 있습니다.
한 가지 주의할 점은 인자 인덱스 리스트가 0이 아닌 1부터 시작(1-based)한다는 점입니다.
Sample Source Code - nonnull.c
c
my_test_function()에서 destsrc 인자가 NULL이어서는 안 된다고 명시했습니다.

Build Results

Check Result
bash
컴파일러가 친절하게 1번과 2번 인자가 NULL이 되어서는 안 된다는 경고 메시지를 출력해 줍니다.
하지만 컴파일 경고는 자칫 실수로 지나치기 쉬우므로, 다음과 같이 컴파일 옵션을 추가하여 에러로 취급하고 빌드 자체가 실패하도록 설정하는 것이 더 안전합니다.
Change to error with -Werror=
bash

Limitations

가장 중요하게 주의해야 할 점은, nonnull 속성을 사용한다고 해서 런타임의 모든 NULL 오류를 완벽하게 막아주지는 못한다는 것입니다.
이 속성은 앞서 언급했듯, 컴파일 타임에 분석하기 쉬운 상황(주로 명시적 상수 입력)에서만 제한적으로 동작합니다.
Situations that cannot be detected
c
위 코드에서 aNULL이지만 빌드는 성공합니다.
Check Result
bash
위 코드에서 변수 a에 명백히 NULL을 담아서 전달했음에도, 상황(최적화 설정 등)에 따라 컴파일러가 이를 즉각적으로 추적하지 못하고 에러 없이 빌드가 성공해버리는 경우가 생깁니다.

A More Critical Consideration

GCC 공식 문서에도 나와 있듯이, 컴파일러는 nonnull 속성으로 지정된 인자가 절대 NULL이 아닐 것이라고 강하게 확신하며 코드 최적화(Optimization)를 수행합니다.
그 결과, 사용자가 런타임 안전을 위해 함수 내부에 꼼꼼히 작성해 둔 방어적 NULL 체크 코드(예: if (dest == NULL) return;)를 불필요한 코드(Dead Code)로 간주하고 컴파일 과정에서 아예 제거해 버릴 수 있는 심각한 위험이 존재합니다.
정리하자면 nonnull 속성은 외부 API에서 프로그래머의 뻔한 실수를 컴파일 타임에 잡기엔 훌륭하지만, 그 속성이 여러분 내부 구현의 안전성을 100% 보장하는 만능열쇠는 아님을 반드시 인지해야 합니다.

Implicitly marking all arguments

인자 인덱스 리스트를 생략하고 nonnull 속성을 사용하면 모든 포인터 인자에 대해 NULL 체크가 수행됩니다.
Use without argument index list
c
Check Result - build fail
bash

Conclusion

비록 감지 능력에 한계는 있지만, 사용자의 실수를 컴파일 타임에 잡아낼 수 있다는 점은 매우 큰 장점입니다.
컴파일러 속성(Attribute)은 runtime overhead가 전혀 없으므로, 앞으로도 이러한 속성들을 적극적으로 활용하는 것을 추천합니다.
Jooojub
System S/W engineer
Explore Tags
Series
    Recent Post
    © 2026. jooojub. All right reserved.