A lo largo del curso mezclamos C y C++ libremente. Hoy formalizamos la pregunta: ¿cuándo vale la pena dar el salto completo, y qué se gana realmente al hacerlo?
En la lección anterior optimizamos rendimiento, un área donde C y C++ suelen rendir de forma prácticamente idéntica cuando se usan bien — la velocidad no es la razón principal para migrar. La razón real para preferir C++ es la seguridad y la expresividad: menos oportunidades de bugs de memoria, código más fácil de mantener a medida que el proyecto crece, y abstracciones que no cuestan rendimiento en tiempo de ejecución ("abstracciones de costo cero").
En C, cada `malloc` necesita su `free` correspondiente, y es responsabilidad tuya rastrear cuándo. Un error aquí produce fugas de memoria o, peor, "use-after-free" (usar memoria ya liberada).
RAII (Resource Acquisition Is Initialization) es la idea de que un recurso (memoria, un archivo abierto, un socket) se adquiere en el constructor de un objeto y se libera automáticamente en su destructor. El compilador garantiza que el destructor se ejecute cuando el objeto sale de scope, sin importar cómo — incluso si hay una excepción o un `return` anticipado.
Lo mismo aplica a punteros individuales con `std::unique_ptr`, que ya usamos en la lección 7 para el `GestorEstados`:
En C, un array dinámico requiere gestionar manualmente el tamaño y la capacidad, y reimplementar el crecimiento cuando se llena. En C++, `std::vector` ya resuelve esto — y de forma probada, sin los bugs off-by-one típicos de una implementación casera.
C++ no es estrictamente superior en todos los contextos. Hay razones legítimas para preferir C puro:
- Estás trabajando en un microcontrolador o entorno embebido con recursos extremadamente limitados, donde cada abstracción, aunque sea "de costo cero" en teoría, agrega complejidad al binario final. - Necesitas compatibilidad estricta con una API o SDK que expone únicamente una interfaz en C (esto es extremadamente común en librerías del sistema y drivers). - Tu equipo ya tiene una base de código en C grande y estable, y una migración parcial introduciría más riesgo del que resuelve.
C++ es, en gran medida, un superconjunto de C — la mayoría del código en C compila directamente como C++. Esto permite una migración gradual, archivo por archivo, en vez de una reescritura total y arriesgada.
Migrar código legado de C a C++ es exactamente el tipo de tarea mecánica y repetitiva donde un asistente de IA brilla, siempre que lo supervises de cerca. Pídele que migre un archivo a la vez (no el proyecto completo de una sola vez), que te muestre el diff exacto de cada cambio, y que te explique por qué cada `malloc`/`free` se reemplazó por su equivalente en C++. Revisa cada cambio de gestión de memoria con especial cuidado — es el área donde un error silencioso de la IA (o tuyo) tiene el mayor costo.
En la lección final vamos a tomar todo lo construido durante este curso y darle el último paso: empaquetarlo y publicarlo para que otras personas puedan jugarlo.
Carlos Montiel es arquitecto de soluciones IA empresarial. Implementa LLMs, Agentes, RAG y orquestadores en empresas de Guatemala y Latinoamérica. Contáctalo para una consultoría.
Contactar a Carlos Montiel