{"schemaVersion":1,"id":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val","title":"Alternativas Memory-Safe a C++: Carbon, Cpp2, Val y Circle en Comparación","description":"Comparación técnica detallada de los lenguajes sucesores de C++, Carbon, Cpp2/cppfront, Val y Circle, con ejemplos reales de interop, análisis de costos de migración y evaluación objetiva de dónde se encuentra cada uno.","language":"es","datePublished":"2025-10-18","dateModified":null,"contentFormat":"text/markdown","content":"Programming Languages\n\n# Alternativas Memory-Safe a C++: Carbon, Cpp2, Val y Circle en Comparación\n\n2025-10-189 min lectura\n\nLucio Durán\nEngineering Manager & AI Solutions Architect\n\nTambién disponible en: [English](<https://lucioduran.com/blog/memory-safe-c-alternatives-carbon-cpp2-val>)\n\n## El Problema Persistente\n\nC++ no tiene una historia de memory safety. Tiene una historia de \"disciplina y tooling\". AddressSanitizer detecta errores en tiempo de ejecución. Los analizadores estáticos detectan algunos en tiempo de compilación. Las C++ Core Guidelines son una guía de estilo, no un mecanismo de cumplimiento. Y después de tres décadas de parches incrementales, se siguen publicando CVEs por use-after-free y buffer overflows.\n\nLa guía de la NSA del 2022, el empuje posterior de CISA, y ahora los requerimientos del EU Cyber Resilience Act de 2025 hicieron que \"simplemente tener más cuidado\" sea una posición insostenible para cualquier producto que toque industrias reguladas. De ahí la necesidad de evaluar alternativas reales.\n\n## Carbon: La Apuesta Interop-First de Google\n\nEl pitch de Carbon es directo: ser para C++ lo que Kotlin fue para Java. Interop bidireccional completa, migración gradual, y una sintaxis modernizada que elimina los footguns más peligrosos.\n\n### Interop en la Práctica\n\nEl siguiente ejemplo importa una clase C++ de audio buffer en [Carbon](<https://github.com/carbon-language/carbon-lang>):\n\n```carbon\nimport Cpp library \"audio/ring_buffer.h\";\n\nfn ProcessBlock(buf: Cpp.RingBuffer*, block_size: i32) -> bool {\n var samples: auto = buf->ReadBlock(block_size);\n if (samples.size() != block_size) {\n return false;\n }\n\n var i: i32 = 0;\n while (i < block_size) {\n samples[i] = ApplyGain(samples[i], 0.7);\n ++i;\n }\n\n return buf->WriteBlock(samples);\n}\n```\n\nLa directiva ` import Cpp ` es genuinamente impresionante cuando funciona. Las pruebas muestran que una implementación completa de ring buffer, incluyendo operaciones de fence con ` std::atomic `, puede importarse y llamarse desde Carbon sin escribir una sola línea de binding. El compilador entiende el name mangling de C++, layouts de vtable, y hasta la semántica de ` std::unique_ptr `.\n\nDonde se rompe todo: el código SIMD. Las codebases que usan extensiones vectoriales de GCC y ` __attribute__((target(\"avx2\"))) ` excesivamente encontrarán que la capa de interop de Carbon se ahoga con esto. Cada función SIMD necesita un wrapper con C-linkage plano, lo cual derrota el propósito del interop seamless.\n\n### Evaluación del Costo de Migración\n\nPara una codebase representativa de 180k líneas, la estimación:\n\n- **Código limpio C++17 moderno** (~60% de la codebase): ~2.5 meses-ingeniero para portar\n- **Código genérico template-heavy** (~25%): ~6 meses-ingeniero, con rediseño significativo\n- **SIMD/intrinsics/platform-specific** (~15%): No factible de portar. Mantener como C++ e interoperar.\n\nEstimación total realista: 8-10 meses-ingeniero para una migración incompleta. Ese es el número honesto que raramente se menciona en las conferencias.\n\n## Cpp2/cppfront: El Middle Ground Pragmático de Herb Sutter\n\n[Cpp2](<https://github.com/hsutter/cppfront>) toma un enfoque fundamentalmente distinto. En vez de construir un lenguaje nuevo con interop, define una sintaxis nueva que transpila a C++20 estándar. El build system existente, el debugger, el profiler, todo sigue funcionando porque la salida es C++.\n\n### La Sintaxis en Acción\n\nLa misma lógica de procesamiento del ring buffer en Cpp2:\n\n```cpp2\nProcessBlock: (inout buf: RingBuffer, block_size: int) -> bool = {\n samples := buf.ReadBlock(block_size);\n if samples.size() != block_size {\n return false;\n }\n\n for (0 ..< block_size) do (i) {\n samples[i] = ApplyGain(samples[i], 0.7);\n }\n\n return buf.WriteBlock(samples);\n}\n```\n\nEl parámetro ` inout ` hace la mutación explícita en el sitio de llamada. Los parámetros son ` in ` (const ref) por defecto, lo que elimina toda una clase de errores de mutación accidental.\n\n### Lo Que Realmente Transpila\n\nEl compilador cppfront convierte eso en aproximadamente este C++20:\n\n```cpp\nauto ProcessBlock(RingBuffer& buf, int block_size) -> bool {\n auto samples = buf.ReadBlock(block_size);\n if (samples.size() != block_size) {\n return false;\n }\n\n for (auto i = 0; i < block_size; ++i) {\n samples[i] = ApplyGain(samples[i], 0.7);\n }\n\n return buf.WriteBlock(samples);\n}\n```\n\nEl insight clave: cppfront agrega safety de inicialización (sin variables sin inicializar), null safety (sin null dereference en ` cpp2::unique_ptr `), bounds safety (subscript chequeado por default), y type safety (sin conversiones narrowing implícitas). Todo enforced a nivel de sintaxis Cpp2, todo compilado a C++20 con zero overhead.\n\n### La Trampa\n\nLos mensajes de error de cppfront son deficientes. Cuando algo sale mal durante la transpilación, se obtiene un error apuntando a una línea en el fuente Cpp2, pero si el error está en el C++ generado, el compilador falla con código generado que el desarrollador no escribió. Una frustración habitual: invertir una tarde entera depurando un fallo de instanciación de plantilla que resulta ser una cláusula ` requires ` faltante que cppfront debería haber generado pero no lo hizo.\n\nAdemás, el soporte de IDEs es limitado. Existe una extensión de VS Code con resaltado de sintaxis básico, pero no hay go-to-definition confiable, no hay herramientas de refactoring, y el language server falla con archivos de más de ~500 líneas. Este aspecto tiene mayor impacto del que suele reconocerse.\n\n## Val: El Enfoque de Mutable Value Semantics\n\n[Val](<https://www.val-lang.dev/>) (antes conocido como Hylo) toma la salida más radical de C++. Su premisa central: si cada valor tiene un único dueño y las mutaciones siempre ocurren in-place, no se necesita borrow checker, no se necesita garbage collection, y se obtiene memory safety con cero overhead en tiempo de ejecución.\n\n### Ownership Sin Borrowing\n\n```val\nfun processBlock(buf: inout RingBuffer, blockSize: Int) -> Bool {\n var samples = buf.readBlock(blockSize)\n if samples.count != blockSize {\n return false\n }\n\n for i in 0 ..< blockSize {\n &samples[i] = applyGain(samples[i], 0.7)\n }\n\n return buf.writeBlock(samples)\n}\n```\n\nEl prefijo ` & ` en ` samples[i] ` es la forma de Val de indicar \"se está mutando esto in-place\". Si se omite, el compilador rechaza la compilación. Es explícito, es visible, y elimina la clase de errores de \"se copió o se creó un alias sin intención\".\n\nLo que hace a Val genuinamente interesante comparado con Rust es la ausencia de anotaciones de lifetime. No hay ` 'a ` lifetimes distribuidos por las firmas de funciones. El sistema de tipos de Val asegura safety a través de value semantics solas, si se posee un valor, se es su único propietario. Sin estado mutable compartido, sin data races por construcción.\n\n### Limitaciones Actuales de Val\n\nVal es el más joven de todos, y se nota. El compilador (construido sobre SIL de Swift) es lento, compilar un módulo de prueba de 3000 líneas tardó 47 segundos versus 3 segundos en Cpp2 y 8 en Carbon. La biblioteca estándar es mínima. No existe una historia de FFI que valga la pena mencionar, es posible llamar funciones C a través de una anotación ` @foreign `, pero la interoperabilidad con C++ no existe todavía.\n\nPara un proyecto greenfield con control total del stack, el diseño de Val es probablemente el más elegante. Para migrar una codebase C++ existente, es inviable en 2026.\n\n## Circle: La Revolución Unipersonal de Sean Baxter\n\n[Circle](<https://www.circle-lang.org/>) es el comodín. Sean Baxter construyó en solitario un compilador de C++ que extiende el lenguaje con características de safety de primera clase, pattern matching, reflection, y lo que fundamentalmente es un lenguaje nuevo que resulta ser un superset estricto de C++.\n\n### Safety Annotations en la Práctica\n\n```cpp\n#feature on safety\n\nvoid ProcessBlock(RingBuffer& buf, int block_size) safe {\n auto samples = buf.ReadBlock(block_size);\n if (samples.size() != block_size) {\n return;\n }\n\n for (int i = 0; i < block_size; ++i) {\n samples[i] = ApplyGain(samples[i], 0.7);\n }\n\n buf.WriteBlock(std2::move(samples));\n}\n```\n\nLa palabra clave ` safe ` en la firma de la función habilita el borrow checker de Circle para esa función. Es posible mezclar código safe y unsafe a nivel de función, lo que constituye la vía de escape más granular de cualquier lenguaje en esta comparación.\n\nCircle compila codebases C++ existentes, incluso proyectos de 180k líneas, al primer intento. Es un compilador de C++, así que naturalmente lo hace. El camino de migración es: compilar el código con Circle, después incrementalmente agregar ` #feature on safety ` a los archivos uno por uno, arreglando las violaciones de safety que el compilador te reporta.\n\n### El Problema del Bus Factor\n\nCircle lo mantiene una sola persona. Una persona increíblemente talentosa, pero una persona. No hay especificación formal, no hay comité, no hay respaldo corporativo. Si Sean decide ir a hacer otra cosa, el proyecto muere efectivamente. Para un proyecto hobby, está bien. ¿Para infraestructura de producción que necesita mantenerse por una década? Ese riesgo es real y es lo que limita una recomendación más amplia de Circle.\n\n## Benchmark: Implementación de Lock-Free Queue\n\nLa misma cola lock-free de Michael-Scott fue implementada en los cuatro lenguajes más el baseline C++20. Los resultados en una instancia [AWS](<https://aws.com/>) c7g.2xlarge (Graviton3, 8 vCPUs):\n\n| Lenguaje | Enqueue/Dequeue ops/sec | Tamaño Binario | Tiempo Compilación |\n| --- | --- | --- | --- |\n| C++20 (baseline) | 14.2M | 48 KB | 1.8s |\n| Carbon | 13.8M | 52 KB | 4.2s |\n| Cpp2 (transpilado) | 14.1M | 48 KB | 2.1s |\n| Val | 11.6M | 67 KB | 12.4s |\n| Circle | 14.2M | 49 KB | 2.3s |\n\nCpp2 y Circle son esencialmente idénticos al baseline C++ en performance, lo cual tiene sentido, emiten C++. Carbon está dentro del 3%, lo que es impresionante para un backend de compilador diferente. La penalización del 18% de Val viene de su alias analysis más conservador; el compilador no pudo probar que ciertas operaciones de punteros en la cola lock-free no aliaseaban.\n\n## Recomendaciones Prácticas\n\nPara organizaciones con una codebase C++ grande existente y presión regulatoria para mejorar memory safety:\n\n1. **Circle** para el camino más rápido a safety annotations sobre código existente, para quienes puedan aceptar el riesgo de mantenedor único.\n2. **Cpp2** para la apuesta organizacional más segura, la salida es C++ estándar, de modo que siempre es posible \"eyectar\" conservando el código transpilado.\n3. **Carbon** para quienes estén dispuestos a esperar 12-18 meses más para que el tooling madure y la codebase sea C++ moderno relativamente limpio.\n4. **Val** solo para proyectos greenfield donde se busque el modelo de safety más elegante y no se necesite interop con C++.\n\nNinguno de estos es Rust. Rust tiene una década de ventaja en ecosistema, tooling y battle-testing en producción. Pero para shops donde 200 ingenieros saben C++ y reentrenar a Rust costaría dos años de velocidad, estos sucesores representan el camino pragmático del medio.\n\nLa migración desde C++ no será un proyecto de fin de semana. Ni siquiera va a ser un proyecto de un trimestre para cualquier codebase no trivial. Pero la presión regulatoria no se va a ir, y comenzar ahora, incluso con herramientas imperfectas, es preferible a esperar una solución perfecta que tal vez nunca llegue.\n\n## Preguntas frecuentes\n\n### ¿Carbon realmente puede interoperar con codebases C++ existentes?\n\nSí, la capa de interop de Carbon puede importar headers C++ directamente via \\`import Cpp\\`. Pero código muy templatizado, APIs basadas en SFINAE y headers llenos de macros todavía dan problemas. Código limpio C++17/20 moderno interopera mejor.\n\n### ¿Cpp2/cppfront está listo para producción?\n\nTodavía no para sistemas críticos. Cppfront transpila a C++20 válido, así que el output es tan production-ready como tu compilador de C++, pero el tooling, los mensajes de error y el soporte del ecosistema siguen madurando a principios de 2026.\n\n### ¿Cómo se diferencia el modelo de ownership de Val del borrow checker de Rust?\n\nVal usa semántica de valores mutables en lugar del enfoque basado en borrows de Rust. En vez de trackear referencias, Val asegura que cada valor tiene un único dueño y las mutaciones pasan in-place. Evita la experiencia de 'pelear contra el borrow checker' eliminando referencias mutables compartidas por completo.\n\n## Tips\n\n1. **Tip:** Evitar reescribir toda la codebase de una. Comenzar envolviendo los boundaries más peligrose es con un módulo del lenguaje sucesor y hacer interop de vuelta. La migración incremental es el único camino viable.\n2. **Tip:** La directiva ` import Cpp ` de Carbon funciona mejor cuando los headers de C++ están limpios, sin macros-como-API, sin trucos SFINAE. Ejecutar ` clang-tidy ` con los modernize passes primero.\n3. **Tip:** Al evaluar Val, comenzar con su semántica de ` mutableValue ` en un pipeline pequeño de procesamiento de datos. El modelo de ownership resulta más claro cuando se lo ve aplicado a transformaciones de grafos.\n\n- c++\n- carbon\n- cpp2\n- val\n- circle\n- memory-safety\n- sistemas\n- cppfront\n\n[Volver al Blog](<https://lucioduran.com/es/blog>)","headings":[{"level":1,"text":"Alternativas Memory-Safe a C++: Carbon, Cpp2, Val y Circle en Comparación","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#title"},{"level":2,"text":"El Problema Persistente","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#el-problema-persistente"},{"level":2,"text":"Carbon: La Apuesta Interop-First de Google","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#carbon-la-apuesta-interop-first-de-google"},{"level":3,"text":"Interop en la Práctica","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#interop-en-la-prctica"},{"level":3,"text":"Evaluación del Costo de Migración","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#evaluacin-del-costo-de-migracin"},{"level":2,"text":"Cpp2/cppfront: El Middle Ground Pragmático de Herb Sutter","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#cpp2cppfront-el-middle-ground-pragmtico-de-herb-sutter"},{"level":3,"text":"La Sintaxis en Acción","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#la-sintaxis-en-accin"},{"level":3,"text":"Lo Que Realmente Transpila","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#lo-que-realmente-transpila"},{"level":3,"text":"La Trampa","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#la-trampa"},{"level":2,"text":"Val: El Enfoque de Mutable Value Semantics","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#val-el-enfoque-de-mutable-value-semantics"},{"level":3,"text":"Ownership Sin Borrowing","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#ownership-sin-borrowing"},{"level":3,"text":"Limitaciones Actuales de Val","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#limitaciones-actuales-de-val"},{"level":2,"text":"Circle: La Revolución Unipersonal de Sean Baxter","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#circle-la-revolucin-unipersonal-de-sean-baxter"},{"level":3,"text":"Safety Annotations en la Práctica","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#safety-annotations-en-la-prctica"},{"level":3,"text":"El Problema del Bus Factor","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#el-problema-del-bus-factor"},{"level":2,"text":"Benchmark: Implementación de Lock-Free Queue","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#benchmark-implementacin-de-lock-free-queue"},{"level":2,"text":"Recomendaciones Prácticas","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#recomendaciones-prcticas"},{"level":2,"text":"Preguntas frecuentes","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#questions"},{"level":3,"text":"¿Carbon realmente puede interoperar con codebases C++ existentes?","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#question-1"},{"level":3,"text":"¿Cpp2/cppfront está listo para producción?","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#question-2"},{"level":3,"text":"¿Cómo se diferencia el modelo de ownership de Val del borrow checker de Rust?","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#question-3"},{"level":2,"text":"Tips","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#article-tips"}],"sections":[{"heading":"Alternativas Memory-Safe a C++: Carbon, Cpp2, Val y Circle en Comparación","level":1,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val","content":"Programming Languages"},{"heading":"Alternativas Memory-Safe a C++: Carbon, Cpp2, Val y Circle en Comparación","level":1,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#title","content":"2025-10-189 min lectura\n\nLucio Durán\nEngineering Manager & AI Solutions Architect\n\nTambién disponible en: [English](<https://lucioduran.com/blog/memory-safe-c-alternatives-carbon-cpp2-val>)"},{"heading":"El Problema Persistente","level":2,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#el-problema-persistente","content":"C++ no tiene una historia de memory safety. Tiene una historia de \"disciplina y tooling\". AddressSanitizer detecta errores en tiempo de ejecución. Los analizadores estáticos detectan algunos en tiempo de compilación. Las C++ Core Guidelines son una guía de estilo, no un mecanismo de cumplimiento. Y después de tres décadas de parches incrementales, se siguen publicando CVEs por use-after-free y buffer overflows.\n\nLa guía de la NSA del 2022, el empuje posterior de CISA, y ahora los requerimientos del EU Cyber Resilience Act de 2025 hicieron que \"simplemente tener más cuidado\" sea una posición insostenible para cualquier producto que toque industrias reguladas. De ahí la necesidad de evaluar alternativas reales."},{"heading":"Carbon: La Apuesta Interop-First de Google","level":2,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#carbon-la-apuesta-interop-first-de-google","content":"El pitch de Carbon es directo: ser para C++ lo que Kotlin fue para Java. Interop bidireccional completa, migración gradual, y una sintaxis modernizada que elimina los footguns más peligrosos."},{"heading":"Interop en la Práctica","level":3,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#interop-en-la-prctica","content":"El siguiente ejemplo importa una clase C++ de audio buffer en [Carbon](<https://github.com/carbon-language/carbon-lang>):\n\n```carbon\nimport Cpp library \"audio/ring_buffer.h\";\n\nfn ProcessBlock(buf: Cpp.RingBuffer*, block_size: i32) -> bool {\n var samples: auto = buf->ReadBlock(block_size);\n if (samples.size() != block_size) {\n return false;\n }\n\n var i: i32 = 0;\n while (i < block_size) {\n samples[i] = ApplyGain(samples[i], 0.7);\n ++i;\n }\n\n return buf->WriteBlock(samples);\n}\n```\n\nLa directiva ` import Cpp ` es genuinamente impresionante cuando funciona. Las pruebas muestran que una implementación completa de ring buffer, incluyendo operaciones de fence con ` std::atomic `, puede importarse y llamarse desde Carbon sin escribir una sola línea de binding. El compilador entiende el name mangling de C++, layouts de vtable, y hasta la semántica de ` std::unique_ptr `.\n\nDonde se rompe todo: el código SIMD. Las codebases que usan extensiones vectoriales de GCC y ` __attribute__((target(\"avx2\"))) ` excesivamente encontrarán que la capa de interop de Carbon se ahoga con esto. Cada función SIMD necesita un wrapper con C-linkage plano, lo cual derrota el propósito del interop seamless."},{"heading":"Evaluación del Costo de Migración","level":3,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#evaluacin-del-costo-de-migracin","content":"Para una codebase representativa de 180k líneas, la estimación:\n\n- **Código limpio C++17 moderno** (~60% de la codebase): ~2.5 meses-ingeniero para portar\n- **Código genérico template-heavy** (~25%): ~6 meses-ingeniero, con rediseño significativo\n- **SIMD/intrinsics/platform-specific** (~15%): No factible de portar. Mantener como C++ e interoperar.\n\nEstimación total realista: 8-10 meses-ingeniero para una migración incompleta. Ese es el número honesto que raramente se menciona en las conferencias."},{"heading":"Cpp2/cppfront: El Middle Ground Pragmático de Herb Sutter","level":2,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#cpp2cppfront-el-middle-ground-pragmtico-de-herb-sutter","content":"[Cpp2](<https://github.com/hsutter/cppfront>) toma un enfoque fundamentalmente distinto. En vez de construir un lenguaje nuevo con interop, define una sintaxis nueva que transpila a C++20 estándar. El build system existente, el debugger, el profiler, todo sigue funcionando porque la salida es C++."},{"heading":"La Sintaxis en Acción","level":3,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#la-sintaxis-en-accin","content":"La misma lógica de procesamiento del ring buffer en Cpp2:\n\n```cpp2\nProcessBlock: (inout buf: RingBuffer, block_size: int) -> bool = {\n samples := buf.ReadBlock(block_size);\n if samples.size() != block_size {\n return false;\n }\n\n for (0 ..< block_size) do (i) {\n samples[i] = ApplyGain(samples[i], 0.7);\n }\n\n return buf.WriteBlock(samples);\n}\n```\n\nEl parámetro ` inout ` hace la mutación explícita en el sitio de llamada. Los parámetros son ` in ` (const ref) por defecto, lo que elimina toda una clase de errores de mutación accidental."},{"heading":"Lo Que Realmente Transpila","level":3,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#lo-que-realmente-transpila","content":"El compilador cppfront convierte eso en aproximadamente este C++20:\n\n```cpp\nauto ProcessBlock(RingBuffer& buf, int block_size) -> bool {\n auto samples = buf.ReadBlock(block_size);\n if (samples.size() != block_size) {\n return false;\n }\n\n for (auto i = 0; i < block_size; ++i) {\n samples[i] = ApplyGain(samples[i], 0.7);\n }\n\n return buf.WriteBlock(samples);\n}\n```\n\nEl insight clave: cppfront agrega safety de inicialización (sin variables sin inicializar), null safety (sin null dereference en ` cpp2::unique_ptr `), bounds safety (subscript chequeado por default), y type safety (sin conversiones narrowing implícitas). Todo enforced a nivel de sintaxis Cpp2, todo compilado a C++20 con zero overhead."},{"heading":"La Trampa","level":3,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#la-trampa","content":"Los mensajes de error de cppfront son deficientes. Cuando algo sale mal durante la transpilación, se obtiene un error apuntando a una línea en el fuente Cpp2, pero si el error está en el C++ generado, el compilador falla con código generado que el desarrollador no escribió. Una frustración habitual: invertir una tarde entera depurando un fallo de instanciación de plantilla que resulta ser una cláusula ` requires ` faltante que cppfront debería haber generado pero no lo hizo.\n\nAdemás, el soporte de IDEs es limitado. Existe una extensión de VS Code con resaltado de sintaxis básico, pero no hay go-to-definition confiable, no hay herramientas de refactoring, y el language server falla con archivos de más de ~500 líneas. Este aspecto tiene mayor impacto del que suele reconocerse."},{"heading":"Val: El Enfoque de Mutable Value Semantics","level":2,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#val-el-enfoque-de-mutable-value-semantics","content":"[Val](<https://www.val-lang.dev/>) (antes conocido como Hylo) toma la salida más radical de C++. Su premisa central: si cada valor tiene un único dueño y las mutaciones siempre ocurren in-place, no se necesita borrow checker, no se necesita garbage collection, y se obtiene memory safety con cero overhead en tiempo de ejecución."},{"heading":"Ownership Sin Borrowing","level":3,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#ownership-sin-borrowing","content":"```val\nfun processBlock(buf: inout RingBuffer, blockSize: Int) -> Bool {\n var samples = buf.readBlock(blockSize)\n if samples.count != blockSize {\n return false\n }\n\n for i in 0 ..< blockSize {\n &samples[i] = applyGain(samples[i], 0.7)\n }\n\n return buf.writeBlock(samples)\n}\n```\n\nEl prefijo ` & ` en ` samples[i] ` es la forma de Val de indicar \"se está mutando esto in-place\". Si se omite, el compilador rechaza la compilación. Es explícito, es visible, y elimina la clase de errores de \"se copió o se creó un alias sin intención\".\n\nLo que hace a Val genuinamente interesante comparado con Rust es la ausencia de anotaciones de lifetime. No hay ` 'a ` lifetimes distribuidos por las firmas de funciones. El sistema de tipos de Val asegura safety a través de value semantics solas, si se posee un valor, se es su único propietario. Sin estado mutable compartido, sin data races por construcción."},{"heading":"Limitaciones Actuales de Val","level":3,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#limitaciones-actuales-de-val","content":"Val es el más joven de todos, y se nota. El compilador (construido sobre SIL de Swift) es lento, compilar un módulo de prueba de 3000 líneas tardó 47 segundos versus 3 segundos en Cpp2 y 8 en Carbon. La biblioteca estándar es mínima. No existe una historia de FFI que valga la pena mencionar, es posible llamar funciones C a través de una anotación ` @foreign `, pero la interoperabilidad con C++ no existe todavía.\n\nPara un proyecto greenfield con control total del stack, el diseño de Val es probablemente el más elegante. Para migrar una codebase C++ existente, es inviable en 2026."},{"heading":"Circle: La Revolución Unipersonal de Sean Baxter","level":2,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#circle-la-revolucin-unipersonal-de-sean-baxter","content":"[Circle](<https://www.circle-lang.org/>) es el comodín. Sean Baxter construyó en solitario un compilador de C++ que extiende el lenguaje con características de safety de primera clase, pattern matching, reflection, y lo que fundamentalmente es un lenguaje nuevo que resulta ser un superset estricto de C++."},{"heading":"Safety Annotations en la Práctica","level":3,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#safety-annotations-en-la-prctica","content":"```cpp\n#feature on safety\n\nvoid ProcessBlock(RingBuffer& buf, int block_size) safe {\n auto samples = buf.ReadBlock(block_size);\n if (samples.size() != block_size) {\n return;\n }\n\n for (int i = 0; i < block_size; ++i) {\n samples[i] = ApplyGain(samples[i], 0.7);\n }\n\n buf.WriteBlock(std2::move(samples));\n}\n```\n\nLa palabra clave ` safe ` en la firma de la función habilita el borrow checker de Circle para esa función. Es posible mezclar código safe y unsafe a nivel de función, lo que constituye la vía de escape más granular de cualquier lenguaje en esta comparación.\n\nCircle compila codebases C++ existentes, incluso proyectos de 180k líneas, al primer intento. Es un compilador de C++, así que naturalmente lo hace. El camino de migración es: compilar el código con Circle, después incrementalmente agregar ` #feature on safety ` a los archivos uno por uno, arreglando las violaciones de safety que el compilador te reporta."},{"heading":"El Problema del Bus Factor","level":3,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#el-problema-del-bus-factor","content":"Circle lo mantiene una sola persona. Una persona increíblemente talentosa, pero una persona. No hay especificación formal, no hay comité, no hay respaldo corporativo. Si Sean decide ir a hacer otra cosa, el proyecto muere efectivamente. Para un proyecto hobby, está bien. ¿Para infraestructura de producción que necesita mantenerse por una década? Ese riesgo es real y es lo que limita una recomendación más amplia de Circle."},{"heading":"Benchmark: Implementación de Lock-Free Queue","level":2,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#benchmark-implementacin-de-lock-free-queue","content":"La misma cola lock-free de Michael-Scott fue implementada en los cuatro lenguajes más el baseline C++20. Los resultados en una instancia [AWS](<https://aws.com/>) c7g.2xlarge (Graviton3, 8 vCPUs):\n\n| Lenguaje | Enqueue/Dequeue ops/sec | Tamaño Binario | Tiempo Compilación |\n| --- | --- | --- | --- |\n| C++20 (baseline) | 14.2M | 48 KB | 1.8s |\n| Carbon | 13.8M | 52 KB | 4.2s |\n| Cpp2 (transpilado) | 14.1M | 48 KB | 2.1s |\n| Val | 11.6M | 67 KB | 12.4s |\n| Circle | 14.2M | 49 KB | 2.3s |\n\nCpp2 y Circle son esencialmente idénticos al baseline C++ en performance, lo cual tiene sentido, emiten C++. Carbon está dentro del 3%, lo que es impresionante para un backend de compilador diferente. La penalización del 18% de Val viene de su alias analysis más conservador; el compilador no pudo probar que ciertas operaciones de punteros en la cola lock-free no aliaseaban."},{"heading":"Recomendaciones Prácticas","level":2,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#recomendaciones-prcticas","content":"Para organizaciones con una codebase C++ grande existente y presión regulatoria para mejorar memory safety:\n\n1. **Circle** para el camino más rápido a safety annotations sobre código existente, para quienes puedan aceptar el riesgo de mantenedor único.\n2. **Cpp2** para la apuesta organizacional más segura, la salida es C++ estándar, de modo que siempre es posible \"eyectar\" conservando el código transpilado.\n3. **Carbon** para quienes estén dispuestos a esperar 12-18 meses más para que el tooling madure y la codebase sea C++ moderno relativamente limpio.\n4. **Val** solo para proyectos greenfield donde se busque el modelo de safety más elegante y no se necesite interop con C++.\n\nNinguno de estos es Rust. Rust tiene una década de ventaja en ecosistema, tooling y battle-testing en producción. Pero para shops donde 200 ingenieros saben C++ y reentrenar a Rust costaría dos años de velocidad, estos sucesores representan el camino pragmático del medio.\n\nLa migración desde C++ no será un proyecto de fin de semana. Ni siquiera va a ser un proyecto de un trimestre para cualquier codebase no trivial. Pero la presión regulatoria no se va a ir, y comenzar ahora, incluso con herramientas imperfectas, es preferible a esperar una solución perfecta que tal vez nunca llegue."},{"heading":"Preguntas frecuentes","level":2,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#questions","content":""},{"heading":"¿Carbon realmente puede interoperar con codebases C++ existentes?","level":3,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#question-1","content":"Sí, la capa de interop de Carbon puede importar headers C++ directamente via \\`import Cpp\\`. Pero código muy templatizado, APIs basadas en SFINAE y headers llenos de macros todavía dan problemas. Código limpio C++17/20 moderno interopera mejor."},{"heading":"¿Cpp2/cppfront está listo para producción?","level":3,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#question-2","content":"Todavía no para sistemas críticos. Cppfront transpila a C++20 válido, así que el output es tan production-ready como tu compilador de C++, pero el tooling, los mensajes de error y el soporte del ecosistema siguen madurando a principios de 2026."},{"heading":"¿Cómo se diferencia el modelo de ownership de Val del borrow checker de Rust?","level":3,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#question-3","content":"Val usa semántica de valores mutables en lugar del enfoque basado en borrows de Rust. En vez de trackear referencias, Val asegura que cada valor tiene un único dueño y las mutaciones pasan in-place. Evita la experiencia de 'pelear contra el borrow checker' eliminando referencias mutables compartidas por completo."},{"heading":"Tips","level":2,"url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#article-tips","content":"1. **Tip:** Evitar reescribir toda la codebase de una. Comenzar envolviendo los boundaries más peligrose es con un módulo del lenguaje sucesor y hacer interop de vuelta. La migración incremental es el único camino viable.\n2. **Tip:** La directiva ` import Cpp ` de Carbon funciona mejor cuando los headers de C++ están limpios, sin macros-como-API, sin trucos SFINAE. Ejecutar ` clang-tidy ` con los modernize passes primero.\n3. **Tip:** Al evaluar Val, comenzar con su semántica de ` mutableValue ` en un pipeline pequeño de procesamiento de datos. El modelo de ownership resulta más claro cuando se lo ve aplicado a transformaciones de grafos.\n\n- c++\n- carbon\n- cpp2\n- val\n- circle\n- memory-safety\n- sistemas\n- cppfront\n\n[Volver al Blog](<https://lucioduran.com/es/blog>)"}],"links":[{"text":"English","url":"https://lucioduran.com/blog/memory-safe-c-alternatives-carbon-cpp2-val"},{"text":"Carbon","url":"https://github.com/carbon-language/carbon-lang"},{"text":"Cpp2","url":"https://github.com/hsutter/cppfront"},{"text":"Val","url":"https://www.val-lang.dev/"},{"text":"Circle","url":"https://www.circle-lang.org/"},{"text":"AWS","url":"https://aws.com/"},{"text":"Volver al Blog","url":"https://lucioduran.com/es/blog"}],"structuredData":[{"@context":"https://schema.org","@graph":[{"@type":"BlogPosting","@id":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val#article","mainEntityOfPage":{"@type":"WebPage","@id":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val"},"headline":"Alternativas Memory-Safe a C++: Carbon, Cpp2, Val y Circle en Comparación","description":"Comparación técnica detallada de los lenguajes sucesores de C++, Carbon, Cpp2/cppfront, Val y Circle, con ejemplos reales de interop, análisis de costos de migración y evaluación objetiva de dónde se encuentra cada uno.","datePublished":"2025-10-18","author":{"@type":"Person","@id":"https://lucioduran.com/#person","name":"Lucio Durán","url":"https://lucioduran.com"},"publisher":{"@type":"Person","@id":"https://lucioduran.com/#person","name":"Lucio Durán","url":"https://lucioduran.com"},"image":"https://lucioduran.com/favicons/og-default.png","url":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val","inLanguage":"es","isPartOf":{"@id":"https://lucioduran.com/blog#blog"},"articleSection":"Programming Languages","keywords":"c++, carbon, cpp2, val, circle, memory-safety, sistemas, cppfront","wordCount":1634,"timeRequired":"PT9M","workTranslation":[{"@type":"BlogPosting","inLanguage":"en","url":"https://lucioduran.com/blog/memory-safe-c-alternatives-carbon-cpp2-val"}]},{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Inicio","item":"https://lucioduran.com/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https://lucioduran.com/es/blog"},{"@type":"ListItem","position":3,"name":"Alternativas Memory-Safe a C++: Carbon, Cpp2, Val y Circle en Comparación","item":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val"}]},{"@type":"FAQPage","mainEntity":[{"@type":"Question","name":"¿Carbon realmente puede interoperar con codebases C++ existentes?","acceptedAnswer":{"@type":"Answer","text":"Sí, la capa de interop de Carbon puede importar headers C++ directamente via `import Cpp`. Pero código muy templatizado, APIs basadas en SFINAE y headers llenos de macros todavía dan problemas. Código limpio C++17/20 moderno interopera mejor."}},{"@type":"Question","name":"¿Cpp2/cppfront está listo para producción?","acceptedAnswer":{"@type":"Answer","text":"Todavía no para sistemas críticos. Cppfront transpila a C++20 válido, así que el output es tan production-ready como tu compilador de C++, pero el tooling, los mensajes de error y el soporte del ecosistema siguen madurando a principios de 2026."}},{"@type":"Question","name":"¿Cómo se diferencia el modelo de ownership de Val del borrow checker de Rust?","acceptedAnswer":{"@type":"Answer","text":"Val usa semántica de valores mutables en lugar del enfoque basado en borrows de Rust. En vez de trackear referencias, Val asegura que cada valor tiene un único dueño y las mutaciones pasan in-place. Evita la experiencia de 'pelear contra el borrow checker' eliminando referencias mutables compartidas por completo."}}]}]}],"contentHash":"97cf96259edf5250747e2346cdf54eeed155fa07a959ac16af4ab54dad003c5a","provenance":{"method":"Deterministic serialization of the server-rendered main element","source":"https://lucioduran.com/es/blog/memory-safe-c-alternatives-carbon-cpp2-val","hashAlgorithm":"sha256","hashScope":"JSON document fields before contentHash and provenance","sourceHTMLBytes":67859,"contentBytes":13418}}
