Se lanza GCC 16
(gcc.gnu.org)- La nueva versión de GNU Compiler Collection marca un punto de inflexión importante al cambiar el estándar predeterminado de C++ a gnu++20 y dejar de considerar experimental la implementación de C++20
- Se añadieron funciones de reflection, contracts y
constexprde C++26, funciones de C++23 y soporte experimental para bibliotecas de C++23 y C++26, y los diagnósticos de errores de template y fallos de restricciones de type traits ahora son más detallados con mensajes jerárquicos - OpenMP y OpenACC ampliaron la asignación de memoria en GPU,
target memsety la API dedevice memcpy, y los front ends de Ada, Fortran, Modula-2 y Algol 68 también incorporan nuevas funciones de lenguaje y compiladores experimentales - x86-64 ahora soporta AMD Zen6, Intel Wildcat Lake e Intel Nova Lake, y también se añadieron funciones específicas por objetivo y cambios de ABI para AMD GPU, LoongArch, IBM z Systems, Solaris y Windows
- Con la eliminación del formato de diagnósticos JSON y el refuerzo de los diagnósticos SARIF y HTML, además de mejoras al analizador estático y la adición de 37 entrypoints en libgdiagnostics, la integración de herramientas y la infraestructura de diagnósticos se amplían de forma importante
Cambios de compatibilidad y mejoras generales
- En Solaris,
int8_ty similares pasaron a sersigned charpara cumplir con el estándar C99, y este es un cambio incompatible- Para más detalles, consulta la sección de Solaris en Porting to GCC 16
- En Solaris, la opción
-pthreadya no predefine_REENTRANT- Para más detalles, consulta la sección de Solaris en Porting to GCC 16
- El formato
jsonde-fdiagnostics-format=fue eliminado, y para diagnósticos legibles por máquina se debe usar SARIF - Link-Time Optimization ahora maneja mejor las sentencias asm de nivel superior con
-flto-toplevel-asm-heuristics - La speculative devirtualization ahora maneja llamadas indirectas a funciones generales y soporta más de una suposición de destino
- El vectorizer ahora identifica con más flexibilidad el paralelismo interno del bucle en reduction, y soporta la vectorización de bucles cuyo número de iteraciones es desconocido y de uncounted loops
- También soporta peeling para alineación en vector length agnostic loops que usan masking, mutual peeling for alignment y la eliminación del cálculo de vector induction en bucles con early break
- GCC Command Options y el option index fueron corregidos para incluir muchas opciones que antes faltaban
- La documentación de GCC-specific attributes fue modernizada para enfatizar mejor la sintaxis estándar de attributes permitida en todos los dialects de C/C++ que soporta GCC
- El material sobre attributes fue reorganizado para reducir repeticiones y se añadió un nuevo attribute index
- La documentación sobre archivos spec de parámetros y opciones se trasladó al GCC internals manual para desarrolladores de GCC y usuarios que necesiten una configuración personalizada de GCC
Cambios principales por lenguaje
-
OpenMP y OpenACC
- Se reforzó el soporte de asignación de memoria de OpenMP, por lo que el allocator con trait
pinnedyompx_gnu_pinned_mem_allocusan la API de CUDA cuando está disponible, mejorando el rendimiento de acceso a esa memoria en GPU de Nvidia - El allocator
ompx_gnu_managed_mem_allocyompx_gnu_managed_mem_space, extensiones de GNU, asignan memoria accesible para el dispositivo desde el host- El dispositivo puede acceder a ella incluso si no se admite unified-shared memory, y aun en sistemas donde toda la memoria del host es accesible para el dispositivo, el comportamiento de migración de páginas puede diferir del de otra memoria
- OpenMP 5.0 agregó soporte limitado de
declare mapperen C/C++, y la cláusulauses_allocatorsincluye tanto los cambios de sintaxis de OpenMP 5.2 como el soporte de punto y coma de OpenMP 6.0 - OpenMP 5.1 agregó soporte inicial del modificador
iteratoren la cláusula map y en el constructotarget updateen C/C++ - OpenMP 5.2 soporta la directiva
begin declare varianten C/C++ - OpenMP 6.0 agregó las rutinas de API
omp_target_memsetyomp_target_memset_async, y también puede usarse la cláusula de assumptionsno_openmp_constructs - Las directivas y cláusulas marcadas como deprecated en OpenMP 5.0, 5.1 y 5.2 generan advertencias de deprecación por defecto, que pueden desactivarse con
-Wno-deprecated-openmp- También se emiten advertencias al usar constantes con nombre o rutinas de API deprecated, y pueden desactivarse con
-Wno-deprecated-declarations
- También se emiten advertencias al usar constantes con nombre o rutinas de API deprecated, y pueden desactivarse con
- OpenACC agregó las rutinas de API
acc_memcpy_deviceyacc_memcpy_device_asyncpara C/C++/Fortran - La directiva
waitde OpenACC 3.0 acepta la cláusulaif, y las rutinas de API Fortranacc_attachyacc_detachde OpenACC 3.3 complementan sus contrapartes de C/C++ de OpenACC 2.6 - En OpenACC 3.4, el uso de la constante con nombre
PARAMETERen la cláusula de datos de Fortran está permitido por la especificación y por GCC, pero en GCC no afecta el comportamiento en tiempo de compilación ni en tiempo de ejecución
- Se reforzó el soporte de asignación de memoria de OpenMP, por lo que el allocator con trait
-
Ada, Fortran, Modula-2, Algol 68
- Las extensiones Ada GNAT agregan Constructor y Destructor, ofreciendo un mecanismo de construcción/finalización bastante distinto del Ada estándar
- Se agregaron los aspectos Implicit with, Structural Generic instantiation y Extended_Access de Ada
Extended_Accesspuede especificarse en declaraciones de tipos de acceso general que apuntan a subtipos de arreglos no restringidos, cambia la representación del puntero y facilita interoperar con lenguajes externos para memoria no asignada por Ada
- Ada puede usar VAST para depuración del compilador con
-gnatd_Vo-gnatd_Wen modo verbose, y se mejoraron el análisis semántico de Reduction Expressions de Ada 2022,Ada.Containers.Bounded_Indefinite_Holders, la implementación de reglas de accesibilidad y el soporte para Android - Fortran cubre coarrays que usan multihilo nativo de memoria compartida en máquinas de un solo nodo y la función
TEAMde Fortran 2018 - Se mejoró el soporte para Parameterized Derived Types de Fortran 2003, y el manejo del parámetro LEN funciona, aunque se necesita un cambio futuro en la representación debido a PR82649
- Fortran 2018 soporta la ampliación de la sentencia
IMPORT, la intrínsecaREDUCEy la nueva sentenciaGENERIC - Fortran 2023 soporta adiciones de funciones trigonométricas como
sinpi, la subrutina intrínsecasplityc_f_pointercon lower bound opcional como argumento - La opción
-fexternal-blas64llama rutinas BLAS externas desdeMATMULcon argumentos enteros de 64 bits, y solo es válida en sistemas de 64 bits y cuando se aplica-ffrontend-optimize - Modula-2 muestra sugerencias ortográficas al procesar listas de importación, nombres de módulos y símbolos en scopes anidados, e incorpora una nueva implementación de wide set y el módulo de biblioteca
M2WIDESET- Los cambios de wide set alteran la ABI y pueden producir errores de enlazado con archivos objeto de versiones anteriores de GCC
- A la biblioteca base de Modula-2 se agregó el módulo de diccionario binario
BinDict, se ofrecen los procedimientosWriteyWriteLnen varios módulos, y la opción-fm2-pathname-root=mejora el acceso a módulos de biblioteca externos - GCC incluye
ga68, un compilador experimental de Algol 68, con el objetivo de implementar el Revised Report y las erratas aprobadas por el subcomité de soporte de Algol 68 de IFIP WG2.1- También se implementan algunas extensiones de GNU y un prelude POSIX; para información del lenguaje, ver el sitio web de Algol 68, y para información del front end, la wiki
C++ y libstdc++
- La versión predeterminada del lenguaje para la compilación de C++ cambia de -std=gnu++17 a -std=gnu++20
- El código que depende de estándares anteriores de C++ debe agregar -std= al build flag o adaptar el código; consulta las porting notes
- El soporte para módulos de C++20 sigue siendo experimental y debe habilitarse con -fmodules
- Se implementaron muchas funciones de C++26, como reflection, annotations for reflection, base class subobject splicing, function parameter reflection, contracts, constexpr exceptions y constexpr virtual inheritance
- P2996R13 Reflection se habilita con
-std=c++26 -freflection - Parte de P2686R4 tiene soporte parcial; structured binding puede ser
constexpr, pero todavía no se permite la referencia a automatic variableconstexpr
- P2996R13 Reflection se habilita con
- Se implementaron funciones de C++23 como P2036R3, P2590R2 y P2246R1
- Los mensajes de error de C++ ahora tienen una estructura jerárquica en problemas relacionados con templates y otros casos, y muestran el anidamiento de mensajes con indentación y viñetas
- El comportamiento anterior puede restaurarse con
-fno-diagnostics-show-nestingo-fdiagnostics-plain-output
- El comportamiento anterior puede restaurarse con
- El soporte experimental para módulos de C++20 agrega la opción
--compile-std-modulepara compilar la header unit<bits/stdc++.h>y los módulosstdystd.compatantes de compilar el archivo fuente- Si la header unit
<bits/stdc++.h>ya está compilada, convierte de forma transparente los#includede headers importables de la biblioteca estándar en importaciones de<bits/stdc++.h> - Se corrigieron muchos bugs reportados
- Si la header unit
- Los diagnósticos de fallos de constraints en type traits de la biblioteca estándar ahora explican con más detalle por qué
is_constructible_v,is_invocable_vy otros devuelvenfalse - En libstdc++, los targets que soportan enteros de 128 bits harán que
std::is_integral<__int128>y traits similares sean siempre true- Antes era true en el dialecto GNU, pero no en el dialecto estricto
- P0952R2: A new specification for
std::generate_canonicalse implementó en todos los modos afectados desde C++11, lo que impacta la salida observable- El comportamiento anterior puede restaurarse definiendo
_GLIBCXX_USE_OLD_GENERATE_CANONICAL
- El comportamiento anterior puede restaurarse definiendo
- El ABI de
std::variantse actualizó para mantener consistencia con los modos C++20 o superiores, y afecta el class layout en ciertos modos de C++17- El comportamiento anterior puede restaurarse definiendo
_GLIBCXX_USE_VARIANT_CXX17_OLD_ABI, y el impacto se limita al modo C++17
- El comportamiento anterior puede restaurarse definiendo
- La ejecución de
std::regexfue reescrita para usar una pila basada en heap en lugar de la pila del sistema, evitando stack overflow al hacer matching sobre strings más grandes - La implementación de C++20 ya no es experimental, y
std::chrono::current_zone()funciona en Windows - Como el soporte de C++20 anterior a GCC 16 era experimental, debe asumirse que los programas que usan componentes de C++20 no son compatibles con releases anteriores
- Entre los cambios de ABI están las funciones de waiting/notifying de
<atomic>, el tipo semaphore de<semaphore>, la sincronización de<syncstream>, los args destd::formaty la representación destd::formatter,std::partial_orderingde<compare>y la representación de algunos adaptors de<ranges>
- Entre los cambios de ABI están las funciones de waiting/notifying de
- El soporte experimental de biblioteca para C++23 incluye
std::mdspan,ranges::starts_with,ranges::ends_with,ranges::shift_left,ranges::shift_rightystd::allocator_traits::allocate_at_least - El soporte experimental de biblioteca para C++26 incluye
std::simd,std::inplace_vector,std::optional<T&>,std::copyable_function,std::function_ref,std::indirect,std::polymorphic,std::owner_equalpara shared pointer y el header<debugging>, entre otros
Soporte de objetivos y sistemas operativos
-
IA-32/x86-64
- Los CPU basados en AMD Zen6 son compatibles con
-march=znver6y habilitan AVX512_BMM, AVX_NE_CONVERT, AVX_IFMA, AVX_VNNI_INT8 y AVX512_FP16 además de las extensiones ISA activadas en Zen5 - Si el soporte AVX512 está activado y el tuning es
znver4,znver5oznver6, la auto-vectorización intenta usar masked vector epilog para reducir el tamaño del código y mejorar el rendimiento - Intel Wildcat Lake es compatible con
-march=wildcatlakee Intel Nova Lake con-march=novalake-march=novalakehabilita adicionalmente APX_F, AVX10.1, AVX10.2 y PREFETCHI sobre las extensiones ISA basadas en Panther Lake
- A partir de GCC 16, se eliminó la activación de AMX-TRANSPOSE, USER_MSR, CLDEMOTE, KL, WIDEKL y PREFETCHI en varios switches
-march= -mavx10.1-256,-mavx10.1-512y-mevex512fueron eliminados, y también desapareció la advertencia de cambio de comportamiento de-mavx10.1- El soporte para AMX-TRANSPOSE fue eliminado en GCC 16, y GCC ya no acepta
-mamx-transpose - La nueva opción de configuración
--enable-x86-64-mfentryhabilita-mfentry, que usa__fentry__en lugar demcountpara profiling en x86-64, y viene activada por defecto en objetivos glibc --enable-tls=DIALECTpermite controlar el dialecto TLS predeterminado; el valor por defecto esgnu, y los valores permitidos songnuygnu2para TLS descriptor
- Los CPU basados en AMD Zen6 son compatibles con
-
AMD GPU, LoongArch, IBM z Systems
- En offloading de AMD GPU, se redujo significativamente la sobrecarga de lanzamiento de regiones target de OpenMP y regiones de cómputo de OpenACC
- Se agregó soporte experimental para el dispositivo AMD Instinct MI300
gfx942, y también se incluyegfx950, que es compatible congfx9-4-genericen la mayoría de los casos - El conjunto predeterminado de compilación multilib para AMD GPU cambió a
gfx908,gfx90a,gfx9-generic,gfx9-4-generic,gfx10-3-generic,gfx11-generic- Si existe una arquitectura genérica, los multilib para dispositivos específicos ya no se compilan por defecto
- Las arquitecturas genéricas requieren ROCm 6.4.0 o superior
- El nuevo conjunto multilib predeterminado requiere assembler y linker de LLVM 20 o superior
- Consulta las AMD installation notes y las configuration notes de GCC
- LoongArch es compatible con tipos enteros de precisión de bits como
_BitInt (N)yunsigned _BitInt (N) - LoongArch admite Function Multi-Versioning mediante el atributo
target_clones, creando versiones de funciones por característica de CPU y seleccionando automáticamente en runtime la versión óptima - Se agregó soporte para la arquitectura LoongArch32, incluyendo la ABI predeterminada
ilp32dy las ABIilp32feilp32s- Cubre tanto la versión estándar de 32 bits LA32 como la versión reducida de 32 bits LA32R, lo que permite generar código objetivo de 32 bits para aplicaciones embebidas
- Esta función depende del soporte de Binutils y glibc
- S/390, System z e IBM z Systems son compatibles con tipos enteros de precisión de bits y con el tipo de punto flotante
_Float16- Las operaciones con
_Float16se realizan por software o con instruccionesfloat
- Las operaciones con
- En la familia S/390 se agregó un stack protector global con
-mstack-protector-guard=globalpara soportar el runtime patching de carga de direcciones canary del kernel de Linux, y también se agregó-mstack-protector-guard-record - El soporte
-m31de la familia S/390 fue marcado como deprecated y será eliminado en una versión futura
-
Sistemas operativos
- Solaris admite de forma sencilla la generación de Solaris CTF, es decir, Compact C Type Format, con la opción
-gsctf - Windows admite TLS nativo, es decir, Thread-Local Storage
- Para activarlo, se requiere especificar
--enable-tlsdurante la configuración y GNU binutils 2.44 o superior
- Para activarlo, se requiere especificar
- Solaris admite de forma sencilla la generación de Solaris CTF, es decir, Compact C Type Format, con la opción
Diagnósticos, plugins y análisis estático
- GCC admite salida de diagnósticos en formato HTML con
-fdiagnostics-add-output=experimental-html - La salida SARIF sigue el dump directory, y en el ejemplo de salida
build-dir/foo.o, GCC 16 escribe SARIF enbuild-dir/foo.c.sarif- GCC 15 escribía en
foo.c.sarifen el mismo ejemplo
- GCC 15 escribía en
- La salida SARIF captura el anidamiento de ubicaciones lógicas y, en muchos casos, incluye la propiedad
descriptionen el objetofix - La
kindsproperty dethreadFlowLocationen SARIF recibe nuevos valoresthrow,catch,unwind,setjmpylongjmppara representar flujo de control no estándar - Los diagnósticos de GCC pueden vincular un grafo dirigido, y también es posible reportar un grafo dirigido global
- El grafo se ignora en el text sink, pero se captura en el SARIF sink, y
experimental-htmllo renderiza sobre SVG usando dot - Configurar
cfgs=yesen el sink de diagnósticos SARIF o HTML activa la captura de la representación intermedia de GCC para todas las funciones de todos los optimization pass
- El grafo se ignora en el text sink, pero se captura en el SARIF sink, y
- Los diagnósticos de GCC pueden referenciar ubicaciones lógicas dentro de archivos XML y JSON
- La herramienta
sarif-replayusa esto para proporcionar un JSON pointer al reportar problemas de entrada SARIF
- La herramienta
- Si
GCC_DIAGNOSTICS_LOGestá definido en el environment, el subsistema de diagnósticos emite un log de texto a stderr o a un archivo nombrado- Se usa para rastrear decisiones internas, como exactamente cuándo y por qué se rechaza un diagnóstico
- Si
EXPERIMENTAL_SARIF_SOCKETestá definido en el environment, GCC intenta conectarse a ese socket al iniciar y envía una notificación JSON-RPC por cada diagnóstico generado - Para los autores de plugins, se agregó un framework de publish/subscribe que entrega mensajes fuertemente tipados entre sender y receiver débilmente acoplados
- En esta release, los topics a los que un plugin puede suscribirse se limitan a eventos de inicio/parada de optimization pass para una función específica y a eventos relacionados con el analizador estático
- Un diagnostic sink de GCC puede tener un objeto
extensioncon un hookfinalizer, y los plugins pueden usarlo para capturar información adicional en el archivo de salida SARIF - En GCC 16 se reorganizó ampliamente la maquinaria de diagnósticos, y no debería afectar a los plugins que solo usan
diagnostic-core.h- Los maintainers de plugins que usan diagnósticos de forma más compleja deben consultar la guía de portabilidad
- El analizador estático puede manejar soporte inicial para C++ Named Return Value Optimization y excepciones, por lo que puede usarse con ejemplos simples de C++
- Debido a problemas de escalabilidad, es muy probable que en esta release siga siendo difícil usarlo en código C++ de producción
-fanalyzerasume que una llamada a una función externa sin el atributonothrowpuede lanzar una excepción cuando-fexceptionsestá habilitado- La nueva opción
-fanalyzer-assume-nothrowdesactiva esta suposición - Sirve para evitar el aumento de warnings en proyectos que usan
-fexceptionsen código C por interoperabilidad con C++, pero donde es poco probable que la API de C utilizada lance excepciones
- La nueva opción
- La estructura de datos de representación del código de usuario de
-fanalyzerfue reescrita para facilitar la comprensión y el debugging, y la ubicación de los diagnósticos mejoró ligeramente- A cambio, aumentó el uso de memoria del analizador
- La estructura de datos de simulación de contenido de memoria de
-fanalyzerfue reimplementada para ser más rápida y más fácil de mantener - El analizador comenzó a usar la maquinaria
value_rangede GCC, eliminando algunos falsos positivos
libgdiagnostics y problemas corregidos
- libgdiagnostics obtiene un total de 37 entrypoints nuevos
- Se agregan 5 entrypoints para trabajar con logical locations
- Se agregan 2 entrypoints para soporte de command-line options y SARIF playback
- Se agregan 12 entrypoints para trabajar con directed graphs, con soporte para crear graphs, pasar un global graph, vincular un diagnostic graph, agregar y consultar nodes y edges, y configurar labels y locations de nodes
- Se agregan 17 entrypoints para construir diagnostic text en un buffer
- Incluyen creación y liberación de message buffers, append de string/text/byte/printf, append de event ids, manejo de rangos de URL/quote/color, dump, y finish de diagnostics basado en buffer junto con agregado de location labels/events
- También se agrega
diagnostic_manager_set_debug_physical_locations() - La lista de problem reports marcados como fixed para la release 16.1 en el GCC bug tracking system puede consultarse en la PR list
- Esa lista puede no estar completa, y es posible que no incluya algunos PR corregidos
1 comentarios
Comentarios en Hacker News
Quiero señalar P2590R2 Explicit lifetime management como una de esas funciones implementadas que la gente debería adoptar, pero que en la práctica probablemente no usará mucho
Esto es para
std::start_lifetime_as, una forma de hacer type-punning de un puntero a un tipo estructurado sin incurrir en UBCasi todo el código zero-copy que maneja búferes de I/O externos se parece más o menos a
reinterpret_cast(buffer.get()), y eso es undefined behavior; ahora, si cambiasreinterpret_castporstart_lifetime_as, deja de ser una mala prácticahttps://en.cppreference.com/cpp/memory/start_lifetime_as
Usar
reinterpret_castaquí es un bugstart_lifetime_ashace una cosa más además de ponerle un nombre estándar bonito al conjuro de laundering de memoria. Semánticamente no toca la memoria, mientras que unmemmoveno-op sí la toca en esencia. En la práctica no hay mucha diferencia porque el compilador puede ver quememmovees no-op y optimizarloread. Si para el compilador es completamente opaco, entonces el kernel o la tarjeta de red o lo que sea estaría construyendo realmente unFoodentro de ese búfer, así que el cast queda completamente justificadostart_lifetime_ases útil cuando el lifetime del búfer es transparente para el compilador y eso puede romper sus supuestos de aliasingParece decir que
Tes un objeto completamente nuevo que contiene subobjetos, y que uno de ellos es de tipoU.Use inicializa como conbit_cast, lo que supongo que pretendía decir que hace cast desde los bits que ya están en esa dirección. Pero comoobjaparece sin definición, supongo que debe referirse a algo en la dirección correctaPero no queda claro qué es E. La página dice “E is the lvalue of type U denoting obj”, pero
objprobablemente sería de un tipo comochar, y si ya fuera de tipoUno haría faltabit_castcharHasta que lo busqué hace un momento no sabía que el calendario de lanzamientos de GCC era tan regular: https://gcc.gnu.org/develop.html
Hasta los 90 se pensaba que era posible hacer grandes lanzamientos estilo waterfall metiendo todas las funciones deseadas, pero cuando el proyecto crece siempre hay alguien trabajando en algo que todavía no está listo. Con lanzamientos regulares al menos puedes seguir entregando versiones a los usuarios
Este enfoque obliga a los desarrolladores con funciones cuya fecha de finalización es incierta a crear toggles para desactivar características inestables, y en la práctica eso se acerca bastante a lo mejor que se puede hacer
Antes iba más lento, y pasé demasiado tiempo esquivando bugs de C++ en GCC 2.95
El simple hecho de que todavía recuerde qué versión era ya dice mucho
Ya lo llevo usando desde hace tiempo. Debian sid tiene paquetes trunk
Como incluye
c++26 reflection, he estado haciendo algunas cosas mágicas con reflection, y para algunos casos como ser-des es mucho mejorOjalá solo hubiera un servidor LSP dentro del ecosistema
libstdestá causando problemasEl supuesto formato
jsonde-fdiagnostics-format=fue eliminado en esta versión, y ahora dicen que si necesitas diagnósticos legibles por máquina en GCC uses SARIFPero también dicen que con
-fdiagnostics-add-output=experimental-htmlahora se pueden sacar diagnósticos en HTMLMe da curiosidad la lógica detrás de quitar la salida JSON y al mismo tiempo agregar salida HTML
Pregunta de principiante: me da curiosidad si GCC usa LLVM internamente en algún lado, o si tiene su propio pipeline de generación de código y optimización. También me interesa saber cómo se compara con LLVM
Soporta más targets que LLVM y, en la mayoría de los casos, genera ejecutables iguales o mejores
Según Wikipedia, GCC es del 22 de marzo de 1987, mientras que la primera versión de LLVM es de 2003
Otra gran diferencia es la licencia. GCC usa GPL y LLVM Apache License, así que ambos proyectos no comparten código
Apple usó
llvm-gccalrededor de 2012, durante la transición de GCC a LLVM, y eso era una combinación del front end de GCC con el back end de LLVMhttps://dragonegg.llvm.org
¿
-Ofasttodavía ignora-fno-fast-math?He usado la fuente unstable durante unos tres meses
Hay programas que no compilan con GCC reciente pero sí funcionan bien con GCC anteriores, así que por ahora en general
gcc 15.xme funciona mejorAun así, si hablamos de compilar más de 3000 programas, la mayoría funcionan bien y solo algunos necesitan parches. Muchas veces esos parches se pueden encontrar en LFS/BLFS, y si corriges problemas puntuales con
sed, normalmente funcionaEspero que esos problemas ya se hayan corregido. Todos necesitamos estabilidad y que “simplemente funcione”