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
By using the nonnull attribute, you can detect at compile-time when a NULL constant is explicitly passed to a function that should not receive NULL for its pointer arguments.
However, a key characteristic of this attribute is that it primarily works when a NULL constant is explicitly written in the argument position during a function call.
There is a limitation where it cannot detect NULL values determined dynamically at runtime or passed indirectly through variables; we will discuss these constraints in detail later.
This attribute can only trigger warnings or errors when used with the -Wnonnull or -Werror=nonnull options during compilation.
If you intentionally use the -Wno-nonnull option, the compiler will not interfere even if the nonnull attribute is applied.
nonnull was first introduced in the GCC 3.3 release and is currently widely used in numerous open-source projects, such as the Linux kernel and glibc, to prevent build-time errors.

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.

The GCC documentation also provides detailed information on this topic.

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

The usage of this attribute is very simple and can be easily understood through sample code.
One thing to note is that the argument index list starts from 1 (1-based), not 0.
Sample Source Code - nonnull.c
c
In my_test_function(), it is specified that the dest and src arguments must not be NULL.

Build Results

Check Result
bash
The compiler helpfully outputs a warning message stating that arguments 1 and 2 must not be NULL.
However, since compilation warnings can easily be overlooked by mistake, it is safer to add compilation options to treat them as errors and ensure the build fails, as shown below.
Change to error with -Werror=
bash

Limitations

The most important thing to be careful about is that using the nonnull attribute does not perfectly prevent all runtime NULL errors.
As mentioned earlier, this attribute works only in limited situations that are easy to analyze at compile-time (primarily explicit constant inputs).
Situations that cannot be detected
c
In the code above, a is NULL, but the build succeeds.
Check Result
bash
Even though NULL is explicitly stored in variable a and passed in the code above, there are cases where the compiler fails to track this immediately due to the situation (e.g., optimization settings), resulting in a successful build without errors.

A More Critical Consideration

As stated in the official GCC documentation, the compiler performs code optimization with a strong assumption that arguments designated with the nonnull attribute will never be NULL.
As a result, there is a serious risk that defensive NULL check code (e.g., if (dest == NULL) return;) meticulously written inside the function for runtime safety may be regarded as "Dead Code" and completely removed during the compilation process.
In summary, while the nonnull attribute is excellent for catching obvious programmer mistakes in external APIs at compile-time, you must realize that it is not a "magic key" that guarantees 100% safety of your internal implementation.

Implicitly marking all arguments

If the argument index list is omitted and the nonnull attribute is used, NULL checks are performed for all pointer arguments.
Use without argument index list
c
Check Result - build fail
bash

Conclusion

Although its detection capabilities have limitations, being able to catch user mistakes at compile-time is a very significant advantage.
Since compiler attributes have zero runtime overhead, it is recommended to actively utilize these attributes in the future.
Jooojub
System S/W engineer
Explore Tags
Series
    Recent Post
    © 2026. jooojub. All right reserved.