gcc options: -Wformat

Explore the -Wformat option in GCC to detect format string errors and security vulnerabilities at compile time.
March 25, 2026

gcc options: -Wformat

Reqruies
  • Compiler: gcc 2.8 or later
  • glibc: 2.2 or later
When developing in C and using functions that employ format strings, such as printf or scanf, it's common to encounter errors caused by passing incorrect argument types.
A key option that helps catch these mistakes early during the compilation stage is -Wformat.

Argument Type and Count Check

First, let's look at a simple example of how the -Wformat option detects actual errors.
format_warning.c
c
Compile Output
bash
The compiler kindly provides a warning asking why an unsigned long type is being printed with %d.
In addition to argument types, it also displays warnings if the number of arguments required by the format string is insufficient, as shown below.
format_warning2.c
c
Compile Output
bash

GCC Documentation for -Wformat

The official GCC documentation describes the -Wformat option as follows.
gcc-7.5.0/Warning-Options
Doc

-Wformat -Wformat=n
Check calls to printf and scanf, etc.,
to make sure that the arguments supplied have types appropriate to the format string specified, and that the conversions specified in the format string make sense.
This includes standard functions, and others specified by format attributes (see Function Attributes),
in the printf, scanf, strftime and strfmon (an X/Open extension, not in the C standard) families (or other target-specific families).
Which functions are checked without format attributes having been specified depends on the standard version selected, and such checks of functions without the attribute specified are disabled by -ffreestanding or -fno-builtin.
The formats are checked against the format features supported by GNU libc version 2.2.
These include all ISO C90 and C99 features, as well as features from the Single Unix Specification and some BSD and GNU extensions.
Other library implementations may not support all these features; GCC does not support warning about features that go beyond a particular library's limitations.
However, if -Wpedantic is used with -Wformat, warnings are given about format features not in the selected standard version (but not for strfmon formats, since those are not in any version of the C standard).

Supported Functions in glibc

It is stated that some standard functions from glibc 2.2 onwards are supported.
So, which glibc functions support -Wformat?
You can find the list of supported functions by examining the GCC source code.
gcc/c-format.c
c
While fully understanding the GCC code is complex, it's clear that the functions are broadly categorized into the printf, scanf, and strftime families.
But what if you want to include user-defined functions that use va_arg() as targets for -Wformat detection, instead of just standard glibc functions?
As mentioned in the documentation we looked at earlier, you can use attribute((format)).
In fact, I am explaining -Wformat first as it serves as the foundation for introducing __attribute__((format)).
There are several types of options in the -Wformat family.
Let's briefly examine them based on GCC 7.5.0.

-Wformat-contains-nul

Checks if there are ignored sections due to a null (NUL, \0) character embedded within the format string.
sample source code - format_contains_nul.c
c
compile and check result
bash

-Wformat-extra-args

Detects cases where more arguments are passed than there are format specifiers.
sample source code - format_extra_args.c
c
compile and check result
bash

-Wformat-overflow

Checks if functions like sprintf might write data larger than the buffer size, potentially causing an overflow.
sample source code - format_overflow.c
c
compile and check result
bash
But what about cases where the size is difficult to predict at compile time?
sample source code - format_overflow.c
c
compile and check result
bash
In reality, there's already a possibility of a buffer overflow due to the format string regardless of the argv value, but the default -Wformat-overflow option doesn't detect it.
In such cases, you can set the inspection level of -Wformat-overflow to 2.
compile with -Wformat-overflow=2
bash

-Wformat-zero-length

Warns if the length of the format string is zero.
sample source code - format_zero_length.c
c
compile and check result
bash
Admittedly, writing code directly like this is rare.
However, code like the following occurs surprisingly often.
sometimes, these ridiculous codes appear
c

-Wformat-nonliteral

Warns if the format string is not a string literal.
sample source code - format_nonliteral.c
c
compile and check result
bash
Specifying fmt as const char will make this warning disappear.
However, there are times when you need to write code that changes the format string (fmt) dynamically.
In these cases, people often use pragmas to ignore the warning for that specific section.

-Wformat-security

Detects cases where the format is not an internal string literal and there are no format arguments.
sample source code - format_security.c
c
compile and check result
bash
Why is this case detected? There's a reason security is in the option name.
If the string is determined by external input rather than being an internal management string, the format string could be changed to something like %n. By manipulating arguments through stack overflows or other means, the code becomes vulnerable to exploits like a Format String Bug.
In other words, it means the code has a serious security hole.
If I get the chance, I'll cover Format String Bug Exploitation techniques in a separate post.

-Wformat-signedness

As the name suggests, this meticulously catches cases where a signed format specifier is used with an unsigned argument, or vice versa.
sample source code - format_signedness.c
c
compile and check result
bash

-Wformat-truncation

In functions that handle strings with a specified length, like snprintf, it detects and warns when data is truncated to fit the specified buffer size.
sample source code - format_truncation.c
c
compile and check result
bash

Conclusion

While the issues discussed above might seem like simple warnings, they can lead to runtime stack overflows or security holes in an application depending on the situation.
Therefore, as a project grows, being able to identify and fix these risk factors during the compilation stage provides a significant advantage to the project's overall quality.
Therefore, it is highly recommended to enable -Wformat or -Werror=format in your compile options to prevent minor mistakes.
Jooojub
System S/W engineer
Explore Tags
Series
    Recent Post
    © 2026. jooojub. All right reserved.