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.
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.
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).
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:
<stdint.h>
(for int8_t
, int32_t
etc.)
and <cstdint>
(for std::int8_t
, std::int32_t
etc.)
<ostream>
(for std::endl
, std::flush
etc.)
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>
.
Copyright (C) Free Software Foundation, Inc. Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.
These pages are maintained by the GCC team. Last modified 2025-01-16.