1 puntos por GN⁺ 2024-03-01 | 1 comentarios | Compartir por WhatsApp

¿Qué hacer si heredaste una base de código existente en C++?

  • Al empezar en un nuevo trabajo, cambiar de equipo o después de que se vaya un colega con mucha experiencia, terminas a cargo de una gran base de código en C++ con una estructura compleja y peculiar.
  • Hay que corregir bugs y agregar nuevas funciones, pero no puedes ignorar la base de código ni deshacerte de ella. Es importante para quien paga el salario, así que también debe ser importante para ti.

Primer paso: hacer que el código funcione en local

  • Haz solo los cambios mínimos necesarios en el código y en el sistema de build para que funcione en tu entorno local. Todavía no hagas un refactor grande.

Eliminar lo innecesario

  • Elimina todo lo que no sea absolutamente necesario para ofrecer las funciones que la empresa o el proyecto open source anuncian y venden.

Llevar el proyecto al siglo XXI

  • Agrega CI (integración continua), linter, fuzzing, formateo automático y demás.

Mejora gradual del código

  • Haz cambios pequeños y graduales en el código. Repítelo una y otra vez hasta llevar el proyecto a un estado aceptable en términos de seguridad, experiencia de desarrollo, corrección y rendimiento.

Considerar reescribir partes en un lenguaje con seguridad de memoria

  • Si es posible, considera reescribir parte del código en un lenguaje con seguridad de memoria.

Especificar las plataformas soportadas

  • Indica en el README los pares <arquitectura>-<sistema operativo> soportados oficialmente. Por ejemplo, x86_64-linux o aarch64-darwin.

Hacer que el build funcione en las máquinas

  • Asegúrate de que se pueda compilar de forma confiable y consistente en todas las plataformas soportadas.

Hacer que las pruebas pasen en las máquinas

  • Si no hay pruebas, escríbelas antes de cambiar el código, haz que pasen y luego vuelve a continuar.

Describir en el README cómo compilar y probar la aplicación

  • Simplifica los comandos de build y test para que incluso alguien no especialista pueda seguirlos fácilmente.

Buscar soluciones rápidas para acelerar el build y las pruebas

  • Busca formas sencillas de mejorar la velocidad del build y de las pruebas sin cambiar el sistema de build.

Eliminar código innecesario

  • Usa advertencias del compilador y el linter para encontrar y eliminar código no utilizado.

Linter

  • No te obsesiones con las reglas del linter; agrega solo algunas básicas e intégralas al ciclo de desarrollo.

Formateo de código

  • En el momento adecuado, aplica de una sola vez un estilo de código a toda la base de código y haz commit de la configuración.

Sanitizers

  • Usa sanitizers para detectar y corregir bugs reales y fugas de memoria.

Agregar un pipeline de CI

  • Automatiza todas las buenas prácticas configuradas (linter, formateo de código, pruebas, etc.) y genera binarios para producción con cada cambio.

Mejora gradual del código

  • Enfócate en objetivos concretos como seguridad, corrección y rendimiento, y aléjate de criterios subjetivos como el "código limpio".

¿Reescribir en un lenguaje con seguridad de memoria?

  • Es un trabajo que sigue en curso y tiene muchas advertencias. Hazlo solo cuando haya una razón clara.

Conclusión

  • Ofrece un plan concreto y paso a paso para salir de una base de código legacy compleja en C++.

Apéndice: gestión de dependencias

  • En C++ no hay una gestión de dependencias real, y la mayoría usa el gestor de paquetes del sistema. Sin embargo, eso es una mala idea.
  • La opinión del autor sobre la gestión de dependencias es usar submódulos de git y compilar desde el código fuente.

Opinión de GN⁺

  • Este artículo ofrece una guía útil, paso a paso, para ingenieros de software junior que heredaron una base de código en C++.
  • Lidiar con código legacy es un desafío común para muchos desarrolladores, y este artículo ofrece consejos prácticos para esa situación.
  • Enfatizar la importancia de las pruebas durante el proceso de mejora de la base de código refleja buenas prácticas de desarrollo de software.
  • La opinión del autor sobre la gestión de dependencias es debatible, y en proyectos reales muchas veces se usan con éxito gestores de paquetes modernos como Conan o vcpkg.
  • Al adoptar tecnologías, hay que considerar las características del proyecto y el nivel técnico del equipo, y este artículo puede servir como un buen punto de partida para tomar esas decisiones.

1 comentarios

 
GN⁺ 2024-03-01
Opiniones de Hacker News
  • En algunos comentarios de Hacker News se ofrecen consejos sobre qué hacer al heredar un proyecto en C++:

    • Builds reproducibles: se recomienda encapsular el entorno de build con herramientas como Docker para que las herramientas y dependencias queden claras y sean reproducibles.
    • Lograr un build limpio con la opción -Wall: resolver las advertencias para corregir problemas en el código y, en casos poco frecuentes, ignorarlas después de entenderlas.
    • Se sugiere hacer pruebas iniciales con herramientas como Valgrind para investigar errores de lectura/escritura.
    • Se recomienda mantener el refactoring dentro de un alcance localizado al principio y evitar rediseños a gran escala antes de entender la estructura completa.
  • Otros comentarios sostienen que es importante introducir primero CI, linting, auto-formatting, etc.:

    • Antes de eliminar partes innecesarias del código, conviene entender cómo funciona el programa, y mediante herramientas de análisis estático se puede obtener visibilidad sobre dónde hace falta trabajar.
  • Un usuario sugiere cambiarse a un nuevo equipo o empresa.

  • También hay comentarios que mencionan la importancia de las herramientas y técnicas para comprender el código:

    • Es importante usar herramientas para indexar el codebase, crear diagramas de secuencia UML y tomar notas como si se lo estuvieras enseñando a otra persona.
  • Un comentario ofrece consejos sobre agregar CI, linters, fuzzing y auto-formatting para modernizar el proyecto:

    • Con CI se busca que también pueda compilarse en otros entornos, y se aprovechan las advertencias del compilador y los analizadores estáticos para identificar problemas en el código.
    • Se configuran pruebas unitarias para las partes importantes del código con el fin de verificar que hagan exactamente lo correcto.
    • El formateo automático tiene menor prioridad, y se recomienda seguir el estilo del mantenedor original.
  • Otro comentario critica la recomendación de reescribir partes en un lenguaje con seguridad de memoria:

    • Es difícil conseguir los recursos necesarios para el trabajo adicional, hace falta conocimiento de otro lenguaje además de C++, y las pruebas pueden volverse más complejas.
  • También hay un comentario que afirma que usar submódulos de git y compilar desde el código fuente es superior a usar un gestor de paquetes:

    • Se señala que es extraño plantear esas críticas antes de probar herramientas como vcpkg.

Estos comentarios ofrecen distintos enfoques y consejos para cuando se hereda un proyecto en C++, y reflejan diversas opiniones sobre gestión del proyecto, comprensión del código, refactoring y estrategias de modernización.