Porting to GCC 15

The GCC 15 release series differs from previous GCC releases in a number of ways. Some of these are a result of bug fixing, and some old behaviors have been intentionally changed to support new standards, or relaxed in standards-conforming ways to facilitate compilation or run-time performance.

Some of these changes are user visible and can cause grief when porting to GCC 15. This document is an effort to identify common issues and provide solutions. Let us know if you have suggestions for improvements!

Note: GCC 15 has not been released yet, so this document is a work-in-progress.

C language issues

C23 by default

GCC 15 changes the default language version for C compilation from -std=gnu17 to -std=gnu23. If your code relies on older versions of the C standard, you will need to either add -std= to your build flags, or port your code to C23. C23 brings the following changes:

Function declarations without parameters

The meaning of function declarations of the form rettype identifier (); such as char *strstr (); changed in C23.

In C17 and earlier, such function declarators specified no information about the number or types of the parameters of the function (C17 6.7.6.3), requiring users to know the correct number of arguments, with each passed argument going through default argument promotion.

In C23 such declarations mean (void) i.e. a function taking no arguments, which can lead to build failures on code that relied on the earlier meaning, such as in this example:


#include <signal.h>

void test()
{
  void (*handler)();
  handler = signal(SIGQUIT, SIG_IGN);
}

<source>: In function 'test':
<source>:6:11: error: assignment to 'void (*)(void)' from incompatible pointer type '__sighandler_t' {aka 'void (*)(int)'} [-Wincompatible-pointer-types]
    6 |   handler = signal(SIGQUIT, SIG_IGN);
      |           ^
In file included from <source>:1:
/usr/include/signal.h:72:16: note: '__sighandler_t' declared here
   72 | typedef void (*__sighandler_t) (int);
      |                ^~~~~~~~~~~~~~

Code such as the above relying on a non-zero number of parameters (such as a single int) can be fixed for C23 by adding the correct parameters to the function declarator, such as via:


  void (*handler)(int);

In other cases the code is simply missing a #include of the correct header, such as with:


  void *malloc();

These can be fixed by including the correct header and removing the non-prototype declaration.

Alternatively you can use -std= to select an earlier version of the C standard.

New keywords

C23 added various new keywords, including bool, true, false, nullptr, and thread_local. Code that uses these for identifiers will need changing. For example typedef int bool; will fail with:


<source>:1:13: error: 'bool' cannot be defined via 'typedef'
    1 | typedef int bool;
      |             ^~~~
<source>:1:13: note: 'bool' is a keyword with '-std=c23' onwards
<source>:1:1: warning: useless type name in empty declaration
    1 | typedef int bool;
      | ^~~~~~~

In C99 and later you can use #include <stdbool.h> which provides definitions of bool, true, and false compatible with C23.

Note that the bool type is not the same as int at ABI level, and so care may be needed porting declarations that appear at an ABI boundary (or serialized to the filesystem).

C++ language issues

Header dependency changes

Some C++ Standard Library headers have been changed to no longer include other headers that were being used internally by the library. As such, C++ programs that used standard library components without including the right headers will no longer compile.

In particular, the following headers are used less widely within libstdc++ and may need to be included explicitly when compiling with GCC 15:

Deprecated headers

Some C++ Standard Library headers now produce deprecation warnings when included. The warnings suggest how to adjust the code to avoid the warning, for example all uses of <cstdbool> and <cstdalign> can simply be removed, because they serve no purpose and are unnecessary in C++ programs. Most uses of <ccomplex> can be adjusted to use <complex> instead, and uses of <ctgmath> can use <cmath> and/or <complex>.