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.
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!
(void), or lowering the level of the warning. See
+casting to (void), 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
-Wunused-but-set-* documentation for more details.
@@ -83,7 +87,7 @@ casting to (void), or lowering the level of the warning. See
-Note that all GCC releases make improvements to conformance 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
Changes between C++17 and C++20 DIS ["Draft International Standard"].
+Note that names removed from C++20 may still appear in headers when
+building under -std=c++20, and only provoke 'deprecated'
+warnings.
-Failures encountered when using Gcc-16 to rebuild numerous open-source -packages included the following: -
- -
-Many failures are caused by using a build option like '-std=c++11
-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.
-
error: 'make_unique' is not a member of 'std'
-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.
+
-C++20 defines new keywords such as 'concept' and 'requires',
-which can no longer be used as identifiers:
-
error: expected identifier before ‘concept’
-
The only solution is to change the name of the identifier. -
- --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: -
error: ‘buffer’ may be used uninitialized [-Werror=maybe-uninitialized]
-
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. -
- -operator!=
-In C++20, u8"str" and u8'c' literals changed
-from type char to type char8_t, leading to errors like:
-
error: invalid conversion from 'const char8_t*' to 'const char*' [-fpermissive]
-
The fix is most commonly a cast from the u8 literal to plain char
-or char const*.
+In C++20, a type that defines operator== gets an
+operator!= provided implicitly by the compiler. This can
+cause ambiguities if the type also defines its own operator!=
+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:
+
error: ambiguous overload for 'operator!=' (operand types are 'daeStringRef' and 'long int')
+
Fixing argument-type signatures is often the simplest fix, but more +complicated cases may require adding or removing overloads.
operator>>operator>> overload for reading from an
istream into a char* was removed because it
offers no way to prevent buffer overrun when reading into a buffer of
unspecified size. This results in errors like:
- error: no match for ‘operator>>’ (operand types are ‘std::istream’ {aka ‘std::basic_istream<char>’} and ‘char*’)
+
error: no match for 'operator>>' (operand types are 'std::istream' {aka 'std::basic_istream<char>'} and 'char*')
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
std::string, which grows as needed.
operator!=
-In C++20, a type that defines operator== gets an
-operator!= provided implicitly by the compiler. This can
-cause ambiguities if the type also defines its own operator!=
-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:
-
error: ambiguous overload for ‘operator!=’ (operand types are ‘daeStringRef’ and ‘long int’)
-
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 -std=gnu++11:
+
error: 'make_unique' is not a member of 'std'
+
+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
+AC_PROG_CXX, it tries but fails to verify that GCC 16's
+compiler supports C++11 language features by default. To work around that,
+remove the AC_PROG_CXX directive from the program's
+configure.ac file and regenerate the makefiles.
+
+
+C++20 defines new keywords such as concept and requires,
+which can no longer be used as identifiers:
+
error: expected identifier before 'concept'
+
The only solutions are to change the name of the identifier,
+or build to an older standard with (e.g.) -std=c++17.
destroythis'
-In C++20, some of what had been deprecated member functions and member
-typedefs of std::allocator were removed, moving them into
-std::allocator_traits, causing complaints about
-lack of these names:
-pointer,
-const_pointer,
-reference,
-const_reference,
-construct,
-destroy,
-rebind,
-is_always_equal, and
-max_size.
+C++20 deprecates implicitly capturing the value of the meta-variable
+this in saved lambda state, provoking warnings if member
+names from the surrounding context are used in the lambda body:
+
warning: implicit capture of 'this' via '[=]' is deprecated in C++20
+
+These can be resolved by adding this or *this,
+as appropriate, to the capture list, such as by [=,this].
-The solution in most cases is to use the corresponding member of
-std::allocator_traits as instantiated on the allocator
-type, instead. Note that explicitly specializing
-std::allocator_traits on a custom allocator type, though
-now undefined behavior, is not warned about.
+In C++20, u8"str" and u8'c' literals changed
+from type char to type char8_t, leading to
+errors like:
+
error: invalid conversion from 'const char8_t*' to 'const char*' [-fpermissive]
+
The fix is most commonly a cast from the u8
+literal to plain char or char const*.
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: -
error: ‘uint64_t’ was not declared in this scope
-
Determine the correct header that declares the name, and #include
-it. The compiler may suggest a header to include.
+
error: 'uint64_t' was not declared in this scope
+
These are fixed by identifying which header declares the name, and +including that. The compiler may suggest the header to include.
-unary_function is not defineddestroy
-Standard library function objects have evolved, and have left early experiments behind.
-All of
-unary_function,
-binary_function,
-pointer_to_unary_function,
-pointer_to_binary_function,
-ptr_fun,
-binder1st,
-binder2nd,
-bind1st,
-bind2nd,
-binary_function,
-mem_fun,
-mem_fun_t,
-mem_fun1_t,
-const_mem_fun_ref_t,
-const_mem_fun1_ref_t,
-mem_fun_ref,
-mem_fun_ref_t,
-mem_fun1_ref_t,
-const_mem_fun_ref_t,
-const_mem_fun1_ref_t,
-unary_negate,
-binary_negate,
-not1, and not2
-have been deprecated and then eliminated from C++20 or earlier Standards,
-supplanted by (a much smaller number of) modern alternatives found in
-<functional>.
+In C++20, many deprecated member functions and member typedefs of
+std::allocator were removed because
+std::allocator_traits has since C++11 provided better
+defaults for those members that should be used instead. This applies
+to former members
+pointer,
+const_pointer,
+reference,
+const_reference,
+construct,
+destroy,
+rebind,
+is_always_equal, and
+max_size.
-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.) std::allocator_traits::destroy
+in place of A::destroy.