Skip to content
HN On Hacker News ↗

GCC 16 Release Series — Changes, New Features, and Fixes

▲ 307 points 52 comments by HeliumHydride 2mo ago HN discussion ↗

Pangram verdict · v3.3

We believe that this document is fully human-written

4 %

AI likelihood · overall

Human
100% human-written 0% AI-generated
SEGMENTS · HUMAN 6 of 6
SEGMENTS · AI 0 of 6
WORD COUNT 1,432
PEAK AI % 9% · §5
Analyzed
Apr 30
backend: pangram/v3.3
Segments scanned
6 windows
avg 239 words each
Distribution
100 / 0%
human / AI fraction
Verdict
Human
Pangram v3.3

Article text · 1,432 words · 6 segments analyzed

Human AI-generated
§1 Human · 1%

GCC 16 Release SeriesChanges, New Features, and Fixes

This page is a "brief" summary of some of the huge number of improvements in GCC 16. You may also want to check out our Porting to GCC 16 page and the full GCC documentation.

Caveats

int8_t etc. are now signed char on Solaris for conformance with the C99 standard. However, this is an incompatible change. See the porting notes for more information. The -pthread option no longer predefines _REENTRANT on Solaris. See the porting notes for more information. The so-called "json" format for -fdiagnostics-format= has been removed in this release. Users seeking machine-readable diagnostics from GCC should use SARIF.

General Improvements

Link-Time Optimization now supports better handling of toplevel asm statements with -flto-toplevel-asm-heuristics. Speculative devirtualization now handles general indirect function calls and supports speculating of more than one target. The vectorizer is now more flexible in identifying in-loop parallelism of reductions. The vectorizer now supports vectorizing uncounted loops or loops for which the number of iterations could not be determined. The vectorizer now supports peeling for alignment for vector length agnostic loops using masking. The vectorizer now supports mutual peeling for alignment. The vectorizer now generates more efficient code for loops with early breaks by eliminating the vector induction computations.

Documentation

The documentation for GCC Command Options and the option index have been corrected to include many previously missing options. The documentation for GCC-specific attributes has been modernized to put more emphasis on the standard attribute syntax, which GCC accepts in all supported dialects of C and C++. The material has also been reorganized to be less repetitive, and there is a new index for attributes. Documentation for parameters and option spec files has been moved from the main GCC manual to the GCC internals manual.

§2 Human · 2%

These features are intended for use by GCC developers and those who need to build custom GCC configurations.

New Languages and Language specific improvements

OpenMP

See the GNU Offloading and Multi-Processing Project (GOMP) page for general information.

The memory allocation support has been enhanced: for allocators with the pinned trait, including ompx_gnu_pinned_mem_alloc, the CUDA API (if available) is used; this improves the performance when accessing this memory on Nvidia GPUs. The newly added ompx_gnu_managed_mem_alloc allocator and the ompx_gnu_managed_mem_space (both GNU extensions) allocate device-accessible memory on the host. Such memory is device accessible even when unified-shared memory is not supported and might have different page-migration behavior than other memory on systems even if all host memory is device accessible. OpenMP 5.0: Limited support for declare mapper has been added for C and C++, only. The uses_allocators clause is now supported, including the OpenMP 5.2 syntax changes and supporting semicolons (OpenMP 6.0); for now, only predefined allocators are supported. OpenMP 5.1: Initial support for the iterator modifier in map clauses and the target update construct has been added for C and C++. OpenMP 5.2: The begin declare variant directive for C and C++ is now supported. OpenMP 6.0: The omp_target_memset and omp_target_memset_async API routines have been added. The no_openmp_constructs assumptions clause can now be used. OpenMP Technical Report 14 (TR14): The named omp_default_device constant has been added to denote the default-device number. For OpenMP directives and clauses that have been deprecated in OpenMP 5.0, 5.1, or 5.2, a deprecation warning is shown, hinting at the to-be-used syntax; the warning is on by default and can be silenced using -Wno-deprecated-openmp.

§3 Human · 7%

Additionally, a deprecation warning is shown when using a deprecated named constant or API routine; this warning can be silenced using -Wno-deprecated-declarations.

OpenACC

See the GCC OpenACC wiki page for general information.

The acc_memcpy_device and acc_memcpy_device_async API routines have been added for C, C++ and Fortran. OpenACC 3.0: The wait directive now accepts the if clause. OpenACC 3.3: The Fortran API routines acc_attach and acc_detach now augment their OpenACC 2.6 C/C++ counterparts. OpenACC 3.4: In Fortran, named constants (PARAMETER) used as var in data clauses are now permitted by the specification and GCC for better compatibility with existing code; however, with GCC, specifying them in data clauses affects neither compile-time nor runtime behavior.

Ada GNAT Extensions

The Constructor [RFC] and Destructor [RFC] extensions add new construction/finalization mechanisms that differ significantly from standard Ada. Those features are inspired by object-oriented programming in other widely used languages (such as C++).

Implicit with allows a stand-alone use clause in the context clause of a compilation unit to imply an implicit with of the same library unit where an equivalent with clause would be allowed.

Structural Generic instantiation [RFC] allows reference to an implicit instance of a generic unit, that is denoted directly by the unit’s name and actual parameters, rather than by a separately declared name. The Extended_Access aspect can be specified on a general access type declaration designating an unconstrained array subtype. It changes the pointer representation and allows easier interfacing with foreign languages when memory for the designated object is not allocated by Ada. In particular, it allows the creation of access to an array slice [RFC].

§4 Human · 8%

Other

VAST (Verifier for the Ada Semantic Tree), enabled with -gnatd_V (or -gnatd_W for verbose mode), can be used to debug the compiler. It checks various properties of the produced Ada Semantic Tree and reports detected violations. The semantic analysis of Ada 2022’s Reduction Expressions has been enhanced. The Ada.Containers.Bounded_Indefinite_Holders unit has been added. Various loopholes in the implementation of accessibility rules have been plugged. Android support has been improved.

C++

C++20 by default: GCC 16 changes the default language version for C++ compilation from -std=gnu++17 to -std=gnu++20. If your code relies on older versions of the C++ standard, you will need to either add -std= to your build flags, or port your code; see the porting notes. N.B. C++20 modules support is still experimental and must be enabled by -fmodules. Several C++26 features have been implemented: P2996R13, Reflection (PR120775, enabled by -std=c++26 -freflection) P3394R4, Annotations for Reflection P3293R3, Splicing a base class subobject P3096R12, Function Parameter Reflection P3491R3, define_static_{string,object,array} (PR120783) P3560R2, Error Handling in Reflection P1306R5, Expansion statements (PR120776) P2900R14, Contracts (PR119061) P2795R5, Erroneous behavior for uninitialized reads (PR114457)

§5 Human · 9%

P1061R10, Structured bindings can introduce a pack (PR117783) P3068R5, constexpr exceptions (PR117785) P3533R2, constexpr virtual inheritance (PR120777) P1494R5, Partial program correctness (PR119060) P3618R0, Allow attaching main to the global module (PR120773) P2843R3, Preprocessing is never undefined (PR120778) P2686R4, constexpr structured bindings and references to constexpr variables (PR117784, only partially, structured bindings can be constexpr but references to constexpr automatic variables still not allowed) Several C++23 features have been implemented: P2036R3, Change scope of lambda trailing-return-type (PR102610) P2590R2, Explicit lifetime management (PR106658) P2246R1, Character encoding of diagnostic text (PR102613) Various C++ error messages (such as for problems involving templates) now have a hierarchical structure. This nesting of messages is presented using indentation and bullet points. The old behavior can be restored via -fno-diagnostics-show-nesting or -fdiagnostics-plain-output. Improved experimental C++20 modules support: New command line option --compile-std-module that conveniently builds the <bits/stdc++.h> header unit and the std and std.compat modules before compiling any source files explicitly specified on the command line. Whenever the <bits/stdc++.h> header unit has been built, GCC now transparently translates an #include of any importable standard library header into an import of <bits/stdc++.h>.

§6 Human · 5%

Many reported bugs have been fixed, thanks to Nathaniel Shead. Constraint failure diagnostics for standard library type traits such as is_constructible_v and is_invocable_v are improved to further elaborate why the trait is false instead of just reporting expression is_foo_v<...> evaluated to false, thanks to Nathaniel Shead.

Runtime Library (libstdc++)

For targets that support 128-bit integers, std::is_integral<__int128> and similar traits are always true. Previously this was only the case when compiling with GNU dialects (-std=gnu++17, -std=gnu++14, etc.) and not with strict dialects (-std=c++17, etc.)

The proposal P0952R2: A new specification for std::generate_canonical was implemented in all affected modes (since C++11), impacting the observed output. The previous behavior can be restored by defining _GLIBCXX_USE_OLD_GENERATE_CANONICAL. The std::variant ABI was updated to make it conforming and consistent with C++20 and later modes. This impacts the layout of classes which have a std::variant as the first member and a base class of the same type as one of the variant's alternatives, if that type is an empty class and has a non-trivial destructor: struct E { ~E(); }; struct Affected : E { std::variant<E, int> mem; // previously stored at offset zero, // uses non-zero offset now }; The previous behavior can be restored by defining _GLIBCXX_USE_VARIANT_CXX17_OLD_ABI. This impacts only C++17 mode. std::regex execution has been rewritten to use a heap-based stack instead of the system stack, avoiding stack overflows when matching larger strings.

Improved support for C++20, including: The C++20 implementation is no longer experimental.