Rickard Lindberg | Blog | Projects
All Posts | 2026 | 2026-01 | 2026-01-06 | All Bibs | All Tags | #c

Can GCC warn about functions that are not called?

Written by Rickard Lindberg .

I was wondering if GCC can warn about functions that are not called.

Here is a sample program where the function bar is not called. Can GCC detect that and warn about it?

#include <stdio.h>

void foo() {
    printf("foo\n");
}

void bar() {
    printf("bar\n");
}

int main() {
    foo();
}

Running GCC with all warnings enabled produces no warnings:

$ gcc -Wall -Werror test.c

Let's try changing the functions to static:

#include <stdio.h>

static void foo() {
    printf("foo\n");
}

static void bar() {
    printf("bar\n");
}

int main() {
    foo();
}

Now GCC detects the unused function:

$ gcc -Wall -Werror test.c
test.c:7:13: error: ‘bar’ defined but not used [-Werror=unused-function]
    7 | static void bar() {
      |             ^~~
cc1: all warnings being treated as errors

That makes sense. In the first example, the unused function bar might be called by some other translation unit, and only at link time can it be detected that it is never called. (Unless you are building a library in which case you can still not know.)

In the Stack Overflow post Is there a way to get warned about unused functions? there are some suggestions how to detect unused functions at link time. I tried the following options:

$ gcc -Wall -Werror test.c -ffunction-sections -Wl,--gc-sections,--print-gc-sections
/usr/bin/ld: removing unused section '.rodata.cst4' in file '/usr/lib/gcc/x86_64-redhat-linux/14/../../../../lib64/crt1.o'
/usr/bin/ld: removing unused section '.data' in file '/usr/lib/gcc/x86_64-redhat-linux/14/../../../../lib64/crt1.o'
/usr/bin/ld: removing unused section '.rodata' in file '/usr/lib/gcc/x86_64-redhat-linux/14/crtbegin.o'
/usr/bin/ld: removing unused section '.text.bar' in file '/tmp/ccO5vFLs.o'

As I understand it, these options modify the binary to not include unused code. Not exactly what I wanted. But we can see in the output above that .text.bar is removed. So it detected that it could be removed.

In rlworkbench, I use a jumbo build, so I can probably turn all functions into static functions and be warned about all unused functions.

However, I have for example string.c that I include in multiple binaries/jumbo builds. And the different binaries might use different subsets of string.c. In that case, I can not make the functions static because binary a might say that functions x is not called, while function x is actually called from binary b.

So the quickest solution might be to temporarily build with the link options to remove unused code, grep for all functions in the output, and see if they are never called or not.

What is Rickard working on and thinking about right now?

Every month I write a newsletter about just that. You will get updates about my current projects and thoughts about programming, and also get a chance to hit reply and interact with me. Subscribe to it below.

Powered by Buttondown (My Newsletter)