[PATCH v2] Changes to gcc-16/porting_to

Jonathan Wakely jwakely@redhat.com
Thu Apr 30 20:08:29 GMT 2026


On Thu, 30 Apr 2026 at 11:43 -0400, Nathan Myers wrote:
>gcc-wwwdocs/Changelog:
>
>	* htdocs/gcc-16/porting_to.html: Numerous edits.
>
>---
>    Changes in v2:
>
>     - Remove s/provide/suggest/ change from template boilerplate text.
>     - Use "Common" only to indicate "both C and C++".
>     - Remove introductory paragraphs about origin in package builds.
>     - Call it "GCC 16" throughout, with NBSP where it might make
>      a difference.
>     - Reproduce compiler message texts using ASCII quote marks.
>     - Move case of transient includes from Common to C++ section.
>     - Remove quote marks from <code> annotations.
>     - Remove case of function-object names not in C++20 but still
>      supported in GCC 16.
>     - Remove case about more "uninitialized variable" warnings.
>     - Rewrite the case for spurious "-std=gnu++11" build option
>      generated by pre-2.73 autoconf.
>     - Add missing <code> tags.
>     - Put "operator!=" case first in the C++ list.
>     - Rewrite suggestion for fix for use of removed allocator members.
>
>   Changes in v1:
>      - 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..69de6da8 100644
>--- a/htdocs/gcc-16/porting_to.html
>+++ b/htdocs/gcc-16/porting_to.html
>@@ -20,13 +20,13 @@ 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
>+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!
> </p>
> 
> <h2 id="c-cpp">Common C and C++ language issues</h2>
> 
>-<h3 id="changes-to-wunused">Changes to -Wunused-but-set-* warnings</h3>
>+<h4 id="changes-to-wunused">Changes to -Wunused-but-set-* warnings</h4>
> 
> <!-- introduced in 0eac9cfee8cb0b21de866a04d5d59685ab35208f -->
> 
>@@ -59,10 +59,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
>   int k = j--;
>   (void) k;
>   int l = 0; // No warning, l used
>@@ -75,7 +75,11 @@ 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.
>+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>
>@@ -83,7 +87,7 @@ casting to <code>(void)</code>, or lowering the level of the warning.  See
> <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
>@@ -99,53 +103,25 @@ 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'
>+warnings.
> </p>
> 
>-<h3 id="c++-common-failures">Common build failures</h3>
>-<p>
>-Failures encountered when using Gcc-16 to rebuild numerous open-source
>-packages included the following:
>-</p>
>-
>-<h4 id="wrong-standard">Library 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>
>+<h3 id="c++-failures">C++ build failures</h3>

The '+' character has special meaning in URLs so should not be used in
an HTML anchor. Please use cpp-failures instead, so that it doesn't
get URL-escaped as c%2b%2b.

> 
>-<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>
>-
>-<h4 id="uninitialized-variable">Uninitialized-variable warnings</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.
>-</p>
>-
>-<h4 id="changes-to-str-literals">Changes to character literals</h4>
>+<h4 id="ambiguous-overload-for-op-not-equal">Ambiguous overload for <code>operator!=</code></h4>
> 
> <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:
>-</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>.
>+In C++20, a type that defines <code>operator==</code> gets an
>+<code>operator!=</code> provided implicitly by the compiler. This can
>+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')
>+</code></p><p>Fixing argument-type signatures is often the simplest fix, but more
>+complicated cases may require adding or removing overloads.
> </p>
> 
> <h4 id="no-match-op-right-shift">No match for <code>operator>></code></h4>
>@@ -155,51 +131,57 @@ 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*')
> </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
> <code>std::string</code>, which grows as needed.
> </p>
> 
>-<h4 id="ambiguous-overload-for-op-not-equal">Ambiguous overload for <code>operator!=</code></h4>
>+<h4 id="wrong-standard">Program uses features from a newer Standard</h4>
> 
> <p>
>-In C++20, a type that defines <code>operator==</code> gets an
>-<code>operator!=</code> provided implicitly by the compiler. This can
>-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’)
>-</code></p><p>Fixing argument-type signatures is often the simplest fix, but more
>-complicated cases may require adding or removing overloads.
>+Many failures are caused by a spurious build option <code>-std=gnu++11</code>:
>+</p><p><code> error: 'make_unique' is not a member of 'std'</code>
>+</p><p>
>+This is usually a consequence of a bug in Autoconf prior to release 2.73
>+that adds this option to Makefiles when, acting on a directive
>+<code>AC_PROG_CXX</code>, it tries but fails to verify that GCC 16's
>+compiler supports C++11 language features by default. To work around that,
>+remove the <code>AC_PROG_CXX</code> directive from the program's
>+<code>configure.ac</code> file and regenerate the makefiles.
>+
>+<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 solutions are to change the name of the identifier,
>+or build to an older standard with (e.g.) <code>-std=c++17</code>.
> </p>
> 
>-<h4 id="no-member-destroy">Has no member named <code>destroy</code></h4>
>+<h4 id="capture-this">Implicit lambda capture of '<code>this</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
>-<code>std::allocator_traits</code>, causing complaints about
>-lack of these names:
>-<code>pointer</code>,
>-<code>const_pointer</code>,
>-<code>reference</code>,
>-<code>const_reference</code>,
>-<code>construct</code>,
>-<code>destroy</code>,
>-<code>rebind</code>,
>-<code>is_always_equal</code>, and
>-<code>max_size</code>.
>+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>
>+
> <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.
>+In C++20, <code>u8"str"</code> and <code>u8'c'</code> literals changed
>+from type <code>char</code> to type <code>char8_t</code>, leading to
>+errors like:
>+</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 <code>u8</code>
>+literal to plain <code>char</code> or <code>char const*</code>.
> </p>
> 
> <h4 id="missing-header-includes">Missing header includes</h4>
>@@ -207,52 +189,34 @@ now undefined behavior, is not warned about.
> <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
>+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>Determine the correct header that declares the name, and <code>#include</code>
>-it. The compiler may suggest a header to include.
>+</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>
> 
>-<h4 id="obsolete-function-objects"><code>unary_function</code> is not defined</h4>
>+<h4 id="no-member-destroy">Has no member named <code>destroy</code></h4>
> 
> <p>
>-Standard library function objects have evolved, and have left early experiments behind.
>-All of
>-<code>unary_function</code>,
>-<code>binary_function</code>,
>-<code>pointer_to_unary_function</code>,
>-<code>pointer_to_binary_function</code>,
>-<code>ptr_fun</code>,
>-<code>binder1st</code>,
>-<code>binder2nd</code>,
>-<code>bind1st</code>,
>-<code>bind2nd</code>,
>-<code>binary_function</code>,
>-<code>mem_fun</code>,
>-<code>mem_fun_t</code>,
>-<code>mem_fun1_t</code>,
>-<code>const_mem_fun_ref_t</code>,
>-<code>const_mem_fun1_ref_t</code>,
>-<code>mem_fun_ref</code>,
>-<code>mem_fun_ref_t</code>,
>-<code>mem_fun1_ref_t</code>,
>-<code>const_mem_fun_ref_t</code>,
>-<code>const_mem_fun1_ref_t</code>,
>-<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,
>-supplanted by (a much smaller number of) modern alternatives found in
>-<code><functional></code>.
>+In C++20, many deprecated member functions and member typedefs of
>+<code>std::allocator</code> were removed because
>+<code>std::allocator_traits</code> has since C++11 provided better
>+defaults for those members that should be used instead. This applies
>+to former members
>+<code>pointer</code>,
>+<code>const_pointer</code>,
>+<code>reference</code>,
>+<code>const_reference</code>,
>+<code>construct</code>,
>+<code>destroy</code>,
>+<code>rebind</code>,
>+<code>is_always_equal</code>, and
>+<code>max_size</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.
>+The solution is to use (e.g.) <code>std::allocator_traits<A>::destroy</code>

This needs to be <A> instead of <A>

OK for wwwdocs with those two changes.

>+in place of <code>A::destroy</code>.
> </p>
> 
> <h2 id="os">Operating Systems</h2>



More information about the Libstdc++ mailing list