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!

Common C and C++ language issues

-

Changes to -Wunused-but-set-* warnings

+

Changes to -Wunused-but-set-* warnings

@@ -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 (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

C++ language issues

-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.

-

Common build failures

-

-Failures encountered when using Gcc-16 to rebuild numerous open-source -packages included the following: -

- -

Library uses features from a newer Standard

- -

-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++ build failures

-

Expected identifier before

- -

-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. -

- -

Uninitialized-variable warnings

- -

-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. -

- -

Changes to character literals

+

Ambiguous overload for 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.

No match for operator>>

@@ -155,51 +131,57 @@ In C++20, the 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.

-

Ambiguous overload for operator!=

+

Program uses features from a newer Standard

-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. + +

Expected identifier before

+ +

+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.

-

Has no member named destroy

+

Implicit lambda capture of 'this'

-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].

+

Changes to character literals

+

-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*.

Missing header includes

@@ -207,52 +189,34 @@ now undefined behavior, is not warned about.

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 defined

+

Has no member named destroy

-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.

- -

specified bound 18446744073709551608 exceeds maximum

-

-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.

Operating Systems