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!
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).
Note that all GCC releases make improvements to conformance which may reject non-conforming, legacy codebases.
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>.
std::vector In GCC 15.1 (and GCC 14.3) std::vector has been extended so that the vector(InputIterator, InputIterator) constructor recognizes iterators that satisfy the C++20 iterator concepts, such as std::random_access_iterator. This can give significant performance improvements for some types of iterator which satisfy the new C++20 concepts but which were only considered to be a Cpp17InputIterator under the rules of C++17 (and earlier standards). However, it can also cause problems for iterator adaptors or iterator facades implemented as templates that wrap another iterator class.
If an adaptor template declares all the possible operators supported for any iterator category (e.g. operator--, operator+, operator[], etc.) but does not constrain those operators to only be present when the wrapped iterator supports them, then the C++20 standard library will incorrectly deduce that the adaptor satisfies the new C++20 iterator concepts. This means the library might attempt to use operator-- on a non-bidirectional iterator, or operator[] on a non-random access iterator, resulting in compilation errors.
Code which encounters these errors should be fixed by constraining the iterator adaptors using concepts (or std::enable_if) so that the operator functions don't appear to be usable unless they will actually compile. For example, the following additions could be used to prevent IteratorAdaptor<Iter> from looking like it supports operator--, operator[], and operator- when Iter doesn't support those:
template<class Iter> class IteratorAdaptor { Iter m_iter; // The underlying iterator that is being adapted. public: // ... IteratorAdaptor& operator--() #ifdef __cpp_lib_ranges requires std::bidirectional_iterator<Iter> #endif { --m_iter; return *this; } reference operator[](difference_type n) const #ifdef __cpp_lib_ranges requires std::random_access_iterator<Iter> #endif { return m_iter[n]; } friend difference_type operator-(const IteratorAdaptor& lhs, const IteratorAdaptor& rhs) #ifdef __cpp_lib_ranges requires std::sized_sentinel_for<Iter, Iter> #endif { return lhs.m_iter - rhs.m_iter; } };
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-05-23.