The GCC 11 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 11. This document is an effort to identify common issues and provide solutions. Let us know if you have suggestions for improvements!
GCC 11 defaults to -std=gnu++17
instead of -std=gnu++14
:
the C++17 standard, plus GNU extensions.
This brings several changes that users should be aware of. The following
paragraphs describe some of these changes and suggest how to deal with them.
Some users might prefer to stay with gnu++14, in which case we suggest to
use the -std=gnu++14
command-line option, perhaps by putting it
in CXXFLAGS
or similar variables in Makefiles.
G++, starting with G++ 7, implements C++17 P0522R0, Matching of template template-arguments excludes compatible templates. As a consequence, the following test is now rejected:
template <int N, int M = N> class A;
template <int N, int M> void fn(A<N, M> &) {}
template <int N, template <int> class TT> void fn(TT<N> &);
template void fn(A<3> &);
because A
is now considered a valid argument for TT
,
so both function templates are valid candidates, and neither is more specialized
than the other, so it's ambiguous.
The new behavior can be disabled independently of other C++17 features with
-fno-new-ttp-matching
.
GCC 11 now issues a diagnostic for ordered comparisons of pointers against constant integers. Commonly this is an ordered comparison against NULL or 0. These should be equality comparisons, not ordered comparisons.
GCC 11 defaults to C++17 which does not allow dynamic exception specifications.
An exception specification like throw(std::runtime_error)
should
be removed or replaced with noexcept(false)
(meaning the function
can throw any type of exception).
An exception specification like throw()
can be replaced with
noexcept
or noexcept(true)
(meaning the function
does not throw exceptions).
GCC 11 now enforces that comparison objects be invocable as const.
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.
The following headers are used less widely in libstdc++ and may need to be included explicitly when compiled with GCC 11:
<limits>
(for std::numeric_limits
)
<memory>
(for std::unique_ptr
, std::shared_ptr
etc.)
<utility>
(for std::pair
, std::tuple_size
,
std::index_sequence
etc.)
<thread>
(for members of namespace std::this_thread
.)
The deprecated iostream members ios_base::io_state
,
ios_base::open_mode
, ios_base::seek_dir
, and
basic_streambuf::stossc
are not available in C++17 mode.
References to those members should be replaced by std::iostate
,
std::openmode
, std::seekdir
, and
basic_streambuf::sbumpc
respectively.
'bind(...)'
is ambiguous
The placeholders for std::tr1::bind
have been changed to use
the same placeholder objects as std::bind
. This means that
following using std::tr1::bind;
an unqualified call to
bind(f, std::tr1::placeholders::_1)
may be ambiguous.
This happens because std::tr1::bind
is brought into scope by
the using-declaration and std::bind
is found by
Argument-Dependent Lookup due to the type of the _1
placeholder.
To resolve this ambiguity replace unqualified calls to bind
with std::tr1::bind
or std::bind
. Alternatively,
change the code to not include the <tr1/functional>
header,
so that only std::bind
is declared.
Programs must be linked to libpthread in order for std::thread
to create new threads of execution.
It is not sufficient to use dlopen
to dynamically load
libpthread.so
at run-time.
__STRICT_ANSI__
The __STRICT_ANSI__
macro is defined by the compiler to
inform the C and C++ standard library headers when a strict language dialect
is being used, e.g. -std=c++17
or -std=c11
rather
than -std=gnu++17
or -std=gnu11
.
If you undefine the __STRICT_ANSI__
macro then you create an
inconsistent state where the compiler is using a strict dialect but the
standard library headers think that GNU extensions are enabled.
The libstdc++ headers in GCC 11 cannot be used in this state and are likely
to produce compilation errors.
If you don't want the macro to be defined, don't use a -std
option that causes it to be defined.
Simply use a -std=gnu++NN
option instead of
-std=c++NN
.
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 2023-01-28.