GCC 16.1 llega con C++20 por defecto, Algol 68 y mejoras para AMD Zen 6

GCC 16.1 ya está disponible como la primera versión estable de la nueva serie GCC 16, una actualización mayor de la GNU Compiler Collection que llega con cambios relevantes para desarrolladores de C, C++, Fortran, Ada, OpenMP, arquitecturas x86-64, AMD GPU, LoongArch, Windows y Solaris. No es una revisión menor: esta versión modifica comportamientos por defecto, añade soporte experimental para nuevos lenguajes y arquitecturas, mejora la vectorización y actualiza piezas importantes de la biblioteca estándar de C++.

La novedad más visible para muchos proyectos será el cambio en C++: GCC 16 pasa a compilar por defecto en modo gnu++20, frente al anterior gnu++17. Para los equipos que mantienen bases de código grandes, especialmente proyectos con dependencias antiguas o compilaciones muy ajustadas, este cambio obliga a revisar scripts, CMake, Makefiles y pipelines de CI. Quien quiera mantener el comportamiento anterior tendrá que fijarlo de forma explícita con opciones como -std=gnu++17 o -std=c++17.

Un salto importante para C++ y su biblioteca estándar

El cambio a C++20 por defecto es una decisión de peso. C++20 ya no es una promesa lejana dentro de GCC, sino el punto de partida para las compilaciones C++ si el desarrollador no especifica otra cosa. Esto puede mejorar la experiencia en proyectos modernos, pero también puede hacer aflorar errores, incompatibilidades o supuestos antiguos que antes pasaban desapercibidos.

GCC 16 incorpora además varias características de C++26, algunas de ellas todavía en terreno experimental. Entre las más llamativas están reflexión, contratos, expansión de sentencias, excepciones en constexpr, herencia virtual en constexpr y mejoras relacionadas con structured bindings. La reflexión, activable con -std=c++26 -freflection, es una de las funciones más esperadas por la comunidad porque puede cambiar cómo se generan metadatos, serialización, bindings, validaciones y herramientas de análisis sobre código C++.

También hay avances en C++23, como cambios en el alcance del tipo de retorno en lambdas, gestión explícita de vida útil y codificación de texto diagnóstico. En paralelo, los mensajes de error de C++ mejoran su estructura: GCC ahora puede mostrar diagnósticos jerárquicos, con sangrías y viñetas, algo especialmente útil cuando el error afecta a plantillas complejas. Quien prefiera el estilo anterior puede usar -fno-diagnostics-show-nesting o -fdiagnostics-plain-output.

La biblioteca estándar libstdc++ también recibe cambios importantes. GCC 16 declara que la implementación de C++20 ya no es experimental, aunque advierte de cambios ABI en componentes que antes sí estaban en fase experimental. Esto afecta a áreas como funciones atómicas de espera y notificación, semáforos, std::format, std::partial_ordering, algunos adaptadores de rangos y determinados usos de std::variant.

Uno de los cambios concretos está en std::variant, cuyo ABI se ha actualizado para ajustarse mejor a C++20 y modos posteriores. Puede afectar al diseño de clases en casos concretos donde std::variant aparece como primer miembro y comparte tipo con una clase base vacía con destructor no trivial. Para proyectos que necesiten mantener el comportamiento antiguo en C++17, GCC permite definir _GLIBCXX_USE_VARIANT_CXX17_OLD_ABI.

También se ha reescrito la ejecución de std::regex para usar una pila basada en heap en lugar de la pila del sistema, lo que evita desbordamientos al trabajar con cadenas grandes. Además, se amplía el soporte experimental de C++23 y C++26 con elementos como std::mdspan, std::simd, std::inplace_vector, std::optional<T&>, std::function_ref, std::copyable_function, std::philox_engine y nuevas funciones en std::stringstream y std::bitset que aceptan std::string_view.

Más vectorización, LTO y análisis estático

Más allá de los lenguajes, GCC 16 introduce mejoras generales en optimización. La vectorización gana flexibilidad al identificar paralelismo dentro de bucles de reducción, al vectorizar bucles cuyo número de iteraciones no se conoce y al generar código más eficiente en bucles con salidas tempranas. También se añade soporte para “mutual peeling” de alineación y para alineación en bucles agnósticos a la longitud vectorial mediante máscaras.

Esto importa porque buena parte del rendimiento moderno depende de la capacidad del compilador para explotar instrucciones vectoriales sin que el programador tenga que escribir intrínsecos a mano. En cargas numéricas, procesamiento de datos, multimedia, simulación o IA clásica, pequeñas mejoras en el vectorizador pueden tener impacto real cuando el código se despliega a gran escala.

La optimización en tiempo de enlace también mejora. Link-Time Optimization incorpora una gestión más fina de declaraciones asm de nivel superior mediante -flto-toplevel-asm-heuristics. Además, la devirtualización especulativa se amplía para manejar llamadas indirectas generales y especular con más de un posible destino. Son cambios de bajo nivel, pero relevantes para aplicaciones grandes donde el compilador puede extraer rendimiento adicional al tener una visión más completa del programa.

El analizador estático de GCC también avanza. -fanalyzer empieza a ser utilizable en ejemplos sencillos de C++, con soporte para Named Return Value Optimization y soporte inicial para excepciones. El propio proyecto avisa de que todavía no es probable que resulte práctico en código C++ de producción por problemas de escala, pero el movimiento es importante. Hasta ahora, muchas herramientas de análisis estático externas han llevado ventaja en C++; que GCC siga reforzando su analizador integrado puede mejorar la detección temprana de errores en compilaciones normales.

La nueva opción -fanalyzer-assume-nothrow permite desactivar la suposición de que una función externa no marcada como nothrow puede lanzar excepciones cuando -fexceptions está activo. Está pensada para proyectos donde esa hipótesis generaría demasiados avisos, por ejemplo código C que se compila con excepciones por interoperabilidad con C++.

OpenMP, OpenACC y nuevos lenguajes en el compilador

GCC 16 también actualiza su soporte de programación paralela. En OpenMP mejora la gestión de memoria, especialmente para asignadores con el rasgo pinned, donde puede usarse la API CUDA si está disponible. Esto permite mejorar el rendimiento al acceder a esa memoria desde GPUs Nvidia. También se añaden extensiones GNU como ompx_gnu_managed_mem_alloc y ompx_gnu_managed_mem_space, orientadas a memoria accesible desde dispositivo en el host.

La compatibilidad con OpenMP 5.0, 5.1, 5.2 y 6.0 sigue creciendo. Hay soporte limitado para declare mapper en C y C++, soporte para uses_allocators, soporte inicial para el modificador iterator en cláusulas map, la directiva begin declare variant y nuevas rutinas como omp_target_memset y omp_target_memset_async. GCC también empieza a emitir advertencias por directivas, cláusulas y API obsoletas en OpenMP, con opciones para silenciarlas cuando sea necesario.

En OpenACC se añaden rutinas como acc_memcpy_device y acc_memcpy_device_async para C, C++ y Fortran. También se amplía el soporte de OpenACC 3.0, 3.3 y 3.4, con cambios relevantes en Fortran.

Ada recibe nuevas extensiones de GNAT, entre ellas mecanismos de constructor y destructor inspirados en lenguajes orientados a objetos como C++, Implicit with, instanciación genérica estructural y el aspecto Extended_Access para ciertos tipos de acceso a arrays. También mejora el análisis semántico de expresiones de reducción de Ada 2022, se añade Ada.Containers.Bounded_Indefinite_Holders y se refuerza el soporte para Android.

Fortran incorpora mejoras en coarrays con memoria compartida nativa en una sola máquina, avances en tipos derivados parametrizados, soporte de extensiones de Fortran 2018 como IMPORT, REDUCE y la nueva sentencia GENERIC, además de funciones trigonométricas añadidas en Fortran 2023 como sinpi. También aparece -fexternal-blas64, útil para llamar a rutinas BLAS externas con enteros de 64 bits en MATMUL.

La sorpresa histórica llega con Algol 68. GCC 16 incluye ahora un compilador experimental para este lenguaje, ga68, que busca implementar el lenguaje descrito por el Revised Report, junto a erratas aprobadas y algunas extensiones GNU. No será una función de uso masivo, pero sí refleja el alcance de GCC como colección de compiladores y como proyecto de preservación y experimentación lingüística.

Nuevas arquitecturas: Zen 6, Nova Lake, LoongArch32 y MI300

En x86-64, GCC 16 añade soporte para procesadores AMD basados en Zen 6 mediante -march=znver6. Esta opción habilita extensiones como AVX512_BMM, AVX_NE_CONVERT, AVX_IFMA, AVX_VNNI_INT8 y AVX512_FP16 sobre la base de Zen 5. Para desarrolladores que compilan software optimizado para servidores, estaciones de trabajo o cargas HPC, este soporte permite preparar binarios más ajustados a la próxima generación de CPUs AMD.

También se añaden objetivos para Intel Wildcat Lake y Nova Lake. -march=wildcatlake se basa en Panther Lake, mientras que -march=novalake incorpora extensiones como APX_F, AVX10.1, AVX10.2 y PREFETCHI. Al mismo tiempo, GCC 16 elimina o cambia el comportamiento de algunas opciones relacionadas con AVX10 y AMX, por lo que los proyectos con flags de compilación muy específicos deberán revisar las notas de migración.

En AMD GPU, el offloading con OpenMP y OpenACC reduce de forma drástica el coste de lanzamiento de regiones de cómputo. También llega soporte experimental para AMD Instinct MI300, gfx942, junto a arquitecturas genéricas como gfx9-4-generic y gfx950, mayormente compatible. La configuración por defecto de multilibs cambia y pasa a requerir herramientas de ensamblador y enlazador de LLVM 20 o superior para el nuevo conjunto.

LoongArch gana soporte para enteros de precisión exacta _BitInt(N) y unsigned _BitInt(N), Function Multi-Versioning con target_clones, y soporte para LoongArch32, incluidas ABI ilp32d, ilp32f e ilp32s. Para el ecosistema chino de hardware y para sistemas embebidos basados en LoongArch, estos cambios son relevantes porque amplían el rango de código que puede compilarse de forma nativa.

En IBM z Systems también llegan _BitInt(N), _Float16, soporte global de stack protector y nuevas opciones relacionadas con el canario de pila. El soporte -m31 queda marcado como obsoleto y será eliminado en una futura versión.

Diagnósticos más útiles para herramientas y CI

GCC 16 dedica una parte importante de sus cambios a los diagnósticos. La antigua salida “json” para -fdiagnostics-format= desaparece y el proyecto recomienda usar SARIF para diagnósticos legibles por máquinas. Esto encaja con el uso creciente de SARIF en herramientas de análisis, plataformas de CI/CD, sistemas de revisión de código y cuadros de mando de seguridad.

Además, GCC puede generar diagnósticos en HTML con -fdiagnostics-add-output=experimental-html. La salida SARIF respeta ahora mejor el directorio de volcado, captura anidamiento de ubicaciones lógicas y añade información más rica en objetos de corrección. También se incorporan nuevos valores para representar flujos de control no estándar, como lanzamiento y captura de excepciones, setjmp y longjmp.

Un cambio interesante es que los diagnósticos pueden asociarse ahora a grafos dirigidos. Los sinks de texto los ignoran, pero SARIF puede capturarlos y la salida HTML experimental puede renderizarlos en SVG mediante dot. Para desarrolladores de compiladores, autores de plugins y equipos que analizan transformaciones internas, esto puede resultar muy útil.

GCC también introduce un marco de publicación/suscripción para autores de plugins, con mensajes tipados entre emisores y receptores. En esta versión, los plugins pueden suscribirse a eventos relacionados con pases de optimización y con el analizador estático. libgdiagnostics incorpora 37 nuevas funciones de entrada, entre ellas soporte para ubicaciones lógicas, grafos dirigidos y construcción de mensajes mediante buffers.

Qué deben revisar los desarrolladores antes de migrar

La actualización a GCC 16.1 será atractiva para proyectos que quieran aprovechar C++20 por defecto, mejores diagnósticos, nuevas arquitecturas y avances en vectorización. Pero no debería hacerse sin pruebas. El cambio de estándar C++ puede romper compilaciones que dependían de comportamientos de gnu++17. Los cambios ABI en partes de libstdc++ pueden exigir recompilar componentes, especialmente si se mezclan bibliotecas construidas con distintas versiones del compilador.

También conviene revisar flags heredados. Algunas opciones relacionadas con AVX10, AMX y arquitecturas Intel ya no se comportan igual o han sido eliminadas. En Solaris hay cambios incompatibles, como que int8_t y tipos similares pasan a ser signed char para ajustarse a C99, y -pthread deja de predefinir _REENTRANT. En Windows, GCC gana soporte para TLS nativo si se configura con --enable-tls y se usan binutils recientes.

La desaparición del formato JSON antiguo para diagnósticos también puede afectar a herramientas internas. Los equipos que consumían esa salida deberían migrar a SARIF. En entornos de CI modernos, ese cambio puede ser positivo, pero requiere adaptar parsers, integraciones y reglas.

GCC 16.1 confirma que el proyecto sigue siendo una pieza central del software libre y de la cadena de herramientas de sistemas. Compila C y C++, pero también Ada, Fortran, Modula-2, D, Objective-C, Go, Rust en vías específicas del ecosistema GCC y ahora experimenta con Algol 68. Sigue siendo un proyecto enorme, mantenido por una comunidad distribuida, y cada versión mayor mezcla mejoras de rendimiento, compatibilidad, lenguajes, arquitecturas y herramientas.

Para quienes administran distribuciones Linux, toolchains internas o entornos de compilación de alto rendimiento, GCC 16 no es solo “otra versión”. Es una actualización que conviene planificar, probar y medir. Para quienes escriben C++ moderno, marca un cambio simbólico: C++20 ya no es una opción avanzada que se activa a mano, sino el nuevo punto de partida.

Preguntas frecuentes

¿Cuál es la principal novedad de GCC 16.1?
Una de las más visibles es que C++ pasa a compilar por defecto en modo gnu++20, en lugar de gnu++17. También hay mejoras en optimización, diagnósticos, OpenMP, OpenACC, Fortran, Ada y soporte de nuevas arquitecturas.

¿Qué debo hacer si mi proyecto aún depende de C++17?
Conviene fijar el estándar de forma explícita en la compilación, por ejemplo con -std=gnu++17 o -std=c++17, y revisar las notas de migración antes de actualizar el compilador en producción.

¿GCC 16 añade soporte para nuevos procesadores?
Sí. Incorpora soporte para AMD Zen 6 con -march=znver6, Intel Wildcat Lake y Nova Lake, además de mejoras para LoongArch, AMD GPU y IBM z Systems.

¿Qué ocurre con los diagnósticos JSON de GCC?
El formato JSON anterior para -fdiagnostics-format= se ha eliminado. Los usuarios que necesiten diagnósticos legibles por máquinas deben migrar a SARIF, que en GCC 16 recibe varias mejoras.

Suscríbete al boletín SysAdmin

Este es tu recurso para las últimas noticias y consejos sobre administración de sistemas, Linux, Windows, cloud computing, seguridad de la nube, etc. Lo enviamos 2 días a la semana.

¡Apúntate a nuestro newsletter!


– patrocinadores –

Noticias destacadas

– patrocinadores –

¡SUSCRÍBETE AL BOLETÍN
DE LOS SYSADMINS!

Scroll al inicio
×