[PATCH] Changes to gcc-16/porting_to

Jonathan Wakely jwakely@redhat.com
Wed Apr 29 14:48:20 GMT 2026


On Tue, 28 Apr 2026 at 18:19 -0400, Nathan Myers wrote:
>gcc-wwwdocs/Changelog:
>
>	* htdocs/gcc-16/porting_to.html: Numerous edits.
>
>---
>
>     - Demote "C and C++" build errors to <h4>, matching C++
>     - Promote 'uninitialized-variable', 'missing-header-includes'
>      common build failures from C++ to "C and C++'.
>     - Clarify comments on unused-but-set increment examples, and
>      note that just silencing the warning is not necessarily the
>      right action.
>     - Add 'capture-this-deprecated' build failure in C++.
>      (From package builds, it showed up only in jemalloc.)
>     - Mention autoconf-2.73 change to AC_PROG_CXX under
>      'wrong-standard', and suggest upgrading autoconf or removing
>      AC_PROG_CXX.
>     - Note that names removed from C++20 may still be seen in GCC-16
>      headers when building with -std=c++20.
>     - Note the -std=c++17 alternative to immediately renaming all
>      'concept' and 'requires' identifiers.
>     - Change 'error:' to 'warning:' in sample diagnostics for uses
>      where the default is only a warning.
>     - Indent example diagnostic messages.
>     - Eliminate the 'specified bound 18446744073709551608' build
>      failure example as too obscure. (It only showed up in jemalloc
>      builds.)
>     - Trivial wording improvements.
>
>(patch attached, page as patched may be viewed at
><http://cantrip.org/porting_to.html>.)

>diff --git a/htdocs/gcc-16/porting_to.html b/htdocs/gcc-16/porting_to.html
>index 2ab0df6f..3011261f 100644
>--- a/htdocs/gcc-16/porting_to.html
>+++ b/htdocs/gcc-16/porting_to.html
>@@ -21,12 +21,18 @@ facilitate compilation or run-time performance.
> <p>
> Some of these changes are user visible and can cause grief when
> porting to GCC 16. This document is an effort to identify common issues
>-and provide solutions. Let us know if you have suggestions for improvements!
>+and suggest solutions. Let us know if you have suggestions for improvements!

This intro paragraph comes from the template used for every release,
let's not change it.

> </p>
> 
>-<h2 id="c-cpp">Common C and C++ language issues</h2>
>+<h2 id="c-cpp">C and C++ language issues</h2>

I think this is "common" as in common to both C and C++, not common as
in frequently encountered. So I think it should stay.

> 
>-<h3 id="changes-to-wunused">Changes to -Wunused-but-set-* warnings</h3>
>+<h3 id="c-c++-common-failures">Common C and C++ build failures</h3>
>+<p>
>+Failures encountered when using Gcc-16 to rebuild numerous open-source
>+C and C++ packages included the following:

I'd prefer to just list the problems and give solutions, without this
part. It doesn't really add value.

(But it should be "GCC 16" though, not "Gcc-16")

>+</p>
>+
>+<h4 id="changes-to-wunused">Changes to -Wunused-but-set-* warnings</h4>
> 
> <!-- introduced in 0eac9cfee8cb0b21de866a04d5d59685ab35208f -->
> 
>@@ -59,10 +65,10 @@ void foo (void) {
>   int f = 0; // No warning, f used
>   int g = f = 5;
>   (void) g;
>-  int h = 0; // No warning, preincrement used
>+  int h = 0; // No warning, preincrement result used
>   int i = ++h;
>   (void) i;
>-  int j = 0; // No warning, postdecrement used
>+  int j = 0; // No warning, postdecrement result used

If I understand correctly, this does match the intended meaning
better, but I'd like to hear from Jakub who added this example.

>   int k = j--;
>   (void) k;
>   int l = 0; // No warning, l used
>@@ -75,20 +81,49 @@ void foo (void) {
> In order to avoid the warnings, one can either remove newly diagnosed
> variables or parameters which aren't used except in pre/post inc/decrements
> or compound assignments, make them used in some way, e.g. just
>-casting to <code>(void)</code>, or lowering the level of the warning.  See
>+casting to <code>(void)</code>, or lowering the level of the warning.
>+But note that an unused variable may indicate a coding error, where
>+some other object was mistakenly used in its place, or a larger change
>+was begun but left incomplete.

Again, I'll leave Jakub to review this.

>+See
> <a href="https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wunused-but-set-variable_003d">
> <code>-Wunused-but-set-*</code></a> documentation for more details.
> </p>
> 
>+<h4 id="uninitialized-variable">Uninitialized-variable warnings</h4>
>+
>+<p>
>+The compiler has similarly become better at identifying and warning about
>+cases where a variable may be getting used without initialization, resulting
>+in undefined behavior, and messages like:
>+</p><p><code> warning: ‘buffer’ may be used uninitialized

Please use plain ' quotes not ‘ and ’
(the former is wht you get printed with LANG=C and the latter are
locale-specific).

>+</code></p><p>These can often be fixed just by initializing the variable
>+to a default value, but they might indicate a deeper problem that such a
>+change would only mask.
>+</p>

The warning isn't new though, and every release can change when/where
you get these warnings. I'm not sure we need to document it here.

>+
>+<h4 id="missing-header-includes">Missing header includes</h4>
>+
>+<p>
>+Programs sometimes use names without having properly #included the header
>+that declares them, relying instead on the name having being declared
>+incidentally via some other header; until it no longer does, resulting in
>+errors like:
>+</p><p><code> error: ‘uint64_t’ was not declared in this scope</code><br>
>+</p><p>These are fixed by identifying which header declares the name, and
>+including that. The compiler may suggest the header to include.
>+</p>

This should be under the C++ issues, where I originally added it. What
changed in GCC 16 is the removal of some transitive includes in
libstdc++, so this doesn't affect C programs. We don't need a generic
tutorial on include-what-you-use for C and C++, we just need to say
that <cstdint> is less widely used within libstdc++.

>+
>+
> <h2 id="cpp">C++ language issues</h2>
> 
> <p>
>-Note that all GCC releases make <a href="https://gcc.gnu.org/bugs/#upgrading"
>+All GCC releases make <a href="https://gcc.gnu.org/bugs/#upgrading"
> >improvements to conformance</a> which may reject non-conforming, legacy
> codebases.
> Other issues arise from C++20 becoming the default choice of published
> Standard to follow (as might have been overridden with, e.g.,
>-<code>-std=c++20</code>), and changes in C++20 from previous Standards.
>+'<code>-std=c++20</code>)', and changes in C++20 from previous Standards.

We don't usually quote options when referred to anywhere in our docs.
The code font already makes it stand out.

> </p>
> 
> <h3 id="removed-features">Deprecated features removed in C++20</h3>
>@@ -99,43 +134,52 @@ been deprecated have been removed from the Standard. These are
> summarized at the top of
> <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2131r0.html"
> >Changes between C++17 and C++20 DIS ["Draft International Standard"]</a>.
>+Note that names removed from C++20 may still appear in headers when
>+building under '<code>-std=c++20</code>', and only provoke 'deprecated'

No quotes around the -std option.

>+warnings.

So then we shouldn't say they've been removed. This is supposed to be
about porting to GCC 16, so if the names are still present in GCC 16
then we shouldn't talk about them being removed.

Did we actually remove anything? I don't think we did. I don't even
remember if we added deprecated attributes. ... git diff shows that I
deprecated std::fabs(const complex<T>&) which was never in the
standard in the first place (see PR120235). I doubt anybody is using
that function, and we didn't remove anything except std::allocator
members which are covered separately below. So I don't think we should
document any removals/deprecations here.

> </p>
> 
>-<h3 id="c++-common-failures">Common build failures</h3>
>+<h3 id="c++-common-failures">Common C++ build failures</h3>
> <p>
> Failures encountered when using Gcc-16 to rebuild numerous open-source
>-packages included the following:
>+C++ packages included the following:

Again, I don't think this adds value.

> </p>
> 
>-<h4 id="wrong-standard">Library uses features from a newer Standard</h4>
>+<h4 id="wrong-standard">Program uses features from a newer Standard</h4>
> 
> <p>
>-Many failures are caused by using a build option like '<code>-std=c++11</code>
>-where the code turns out to depend on features from a later Standard, such as when
>-building with a new version of a library that has begun using such features.
>-</p><code>error: 'make_unique' is not a member of 'std'</code>
>-</p>Just removing that option from the command line may suffice, although
>-you might then need to update other code reliant on features that have
>-been removed from the later Standard.</p>
>+Many failures are caused by using a build option like '<code>-std=c++11</code>'

I don't think Autoconf ever added -std=c++11, only -std=gnu++11, so
this is inaccurate.

>+where the code turns out to depend on features from a later Standard:
>+</p><p><code> error: 'make_unique' is not a member of 'std'</code>
>+</p><p>Just removing that option from the command line may suffice,
>+as GCC-16 now defaults to providing C++20. Note that <code>autoconf</code>

"GCC 16" not "GCC-16"

>+prior to release 2.73, if told '<code>AC_PROG_CXX</code>' (meaning, verify the
>+compiler supports C++11 features), upon checking GCC-16 incorrectly
>+concludes it must add '<code>-std=gnu++11</code>' to the makefile.
>+You can upgrade <code>autoconf</code>, or simply remove
>+'<code>AC_PROG_CXX</code>' from the program's <code>configure.ac</code> file,
>+and then reconstruct your project build scripts.

I think this item buries the lede. The problem is the Autoconf bug,
and nobody will be trying to use e.g. make_unique with -std=c++11 in
existing code that already compiles with GCC 15 and earlier. It's only
a problem when switching to GCC 16 *and* using a configure script
generated by the buggy Autoconf 2.72 AC_PROG_CXX macro.

So maybe start by saying something about unexpected -std=gnu++11
options being added to makefiles and causing build failures, then
explain that it's due to Autoconf and then give your recommendation
for fixing it.

> 
> <h4 id="expected-identifier-before">Expected identifier before</h4>
> 
> <p>
> C++20 defines new keywords such as '<code>concept</code>' and '<code>requires</code>',
> which can no longer be used as identifiers:
>-</p><p><code> error: expected identifier before ‘concept’
>-</code></p><p>The only solution is to change the name of the identifier.
>+</p><p><code> error: expected identifier before ‘concept’

Plain '' quotes not ‘’

>+</code></p><p>The only solutions are to change the name of the identifier,
>+or build to an older standard, like '<code>-std=c++17</code>'.
> </p>
> 
>-<h4 id="uninitialized-variable">Uninitialized-variable warnings</h4>
>+<h4 id="capture-this">Implicit lambda capture of '<code>this</code>'</h4>
> 
> <p>
>-The compiler is now better at identifying and warning about cases
>-where a variable may be getting used without initialization, resulting
>-in undefined behavior, and errors like:
>-</p><p><code> error: ‘buffer’ may be used uninitialized [-Werror=maybe-uninitialized]
>-</code></p><p>These can often be fixed by just initializing the variable to a default
>-value, but they may indicate a deeper problem that this would only mask.
>+C++-20 deprecates implicitly capturing the value of the meta-variable
>+'<code>this</code>' in saved lambda state, provoking warnings if member
>+names from the surrounding context are used in the lambda body:
>+</p><p><code> warning: implicit capture of ‘this’ via ‘[=]’ is deprecated in C++20</code>
>+</p><p>
>+These can be resolved by adding '<code>this</code>' or '<code>*this</code>',
>+as appropriate, to the capture list, such as by '<code>[=,this]</code>'.
> </p>
> 
> <h4 id="changes-to-str-literals">Changes to character literals</h4>
>@@ -143,7 +187,7 @@ value, but they may indicate a deeper problem that this would only mask.
> <p>
> In C++20, <code>u8"str"</code> and <code>u8'c'</code> literals changed
> from type char to type char8_t, leading to errors like:

<code> tags around char and char8_t

>-</p><p><code>  error: invalid conversion from 'const char8_t*' to 'const char*' [-fpermissive]
>+</p><p><code> error: invalid conversion from 'const char8_t*' to 'const char*' [-fpermissive]
> </code></p><p> The fix is most commonly a cast from the u8 literal to plain <code>char</code>
> or <code>char const*</code>.
> </p>
>@@ -155,7 +199,7 @@ In C++20, the <code>operator>></code> overload for reading from an
> <code>istream</code> into a <code>char*</code> was removed because it
> offers no way to prevent buffer overrun when reading into a buffer of
> unspecified size. This results in errors like:
>-</p><p><code> error: no match for ‘operator>>’ (operand types are ‘std::istream’ {aka ‘std::basic_istream<char>’} and ‘char*’)
>+</p><p><code> error: no match for ‘operator>>’ (operand types are ‘std::istream’ {aka ‘std::basic_istream<char>’} and ‘char*’)

Plain '' quotes not ‘’

> </code></p><p>
> A fix is to read into a native array, which uses the bound to prevent
> overrun and leaves any extra characters unread, or to read into an
>@@ -171,7 +215,7 @@ cause ambiguities if the type also defines its own <code>operator!=</code>
> with an unconventional signature, such as only supporting comparisons
> of non-const types (often a mistake, because comparison typically does
> not require altering its arguments). This provokes errors like:
>-</p><p><code> error: ambiguous overload for ‘operator!=’ (operand types are ‘daeStringRef’ and ‘long int’)
>+</p><p><code> error: ambiguous overload for ‘operator!=’ (operand types are ‘daeStringRef’ and ‘long int’)

I think this item about default comparisons should be first. I expect
it to be one of the most common problems when switching to C++20.

> </code></p><p>Fixing argument-type signatures is often the simplest fix, but more
> complicated cases may require adding or removing overloads.
> </p>
>@@ -179,8 +223,8 @@ complicated cases may require adding or removing overloads.
> <h4 id="no-member-destroy">Has no member named <code>destroy</code></h4>
> 
> <p>
>-In C++20, some of what had been deprecated member functions and member
>-typedefs of <code>std::allocator</code> were removed, moving them into
>+In C++20, many deprecated member functions and member typedefs of
>+<code>std::allocator</code> were removed, moving them into
> <code>std::allocator_traits</code>, causing complaints about

They weren't moved into allocator_traits in C++20, they were there
since C++11. Maybe something like:

In C++20, many deprecated member functions and member typedefs of
<code>std::allocator</code> were removed because
<code>std::allocator_traits</code> provides defaults for those
members and those should be used instead.

> lack of these names:
> <code>pointer</code>,
>@@ -195,23 +239,8 @@ lack of these names:
> </p>
> 
> <p>
>-The solution in most cases is to use the corresponding member of
>-<code>std::allocator_traits</code> as instantiated on the allocator
>-type, instead. Note that explicitly specializing
>-<code>std::allocator_traits</code> on a custom allocator type, though
>-now undefined behavior, is not warned about.
>-</p>
>-
>-<h4 id="missing-header-includes">Missing header includes</h4>
>-
>-<p>
>-Programs sometimes use names without having properly #included the header
>-that declares them, relying instead on the name having being declared
>-accidently via some other header; until it no longer does, resulting in
>-errors like:
>-</p><p><code> error: ‘uint64_t’ was not declared in this scope</code><br>
>-</p><p>Determine the correct header that declares the name, and <code>#include</code>
>-it. The compiler may suggest a header to include.
>+The solution is to use the corresponding member of <code>std::allocator_traits</code>
>+as instantiated on the allocator type, instead.

I think something like "using allocator_traits<A>::foo instead of
A::foo" would be clearer than "as instead on the allocator type".

> </p>
> 
> <h4 id="obsolete-function-objects"><code>unary_function</code> is not defined</h4>
>@@ -242,17 +271,10 @@ All of
> <code>unary_negate</code>,
> <code>binary_negate</code>,
> <code>not1</code>, and <code>not2</code>
>-have been deprecated and then eliminated from C++20 or earlier Standards,
>+have been deprecated in earlier Standards and then eliminated from C++20,
> supplanted by (a much smaller number of) modern alternatives found in
>-<code><functional></code>.
>-</p>
>-
>-<h4 id="specified-bound-overflow">specified bound 18446744073709551608 exceeds maximum</h4>
>-
>-<p>
>-GCC has become better at recognizing when a value passed to an allocator could potentially
>-exceed the maximum permitted, 0x7ff...ff, such as by rounding a passed-in size up to the
>-usual alignment without capping the result.
>+<code><functional></code>. GCC-16 thus far only deprecates these names,
>+but does not actually remove them.

std::unary_function and friends were given the deprecated attribute in
2022 for GCC 12 so I don't think this needs to be documented here.

> </p>
> 
> <h2 id="os">Operating Systems</h2>



More information about the Libstdc++ mailing list