Saltar al contenido
Topos Uranos

Resumen

Esta clase cierra la octava unidad y, con ella, el curso. Recoge lo logrado en las tres clases de la unidad; reconstruye la cadena de conceptos que va de la interfaz de un módulo a la depuración como método; separa lo que de ello vale en cualquier lenguaje de lo que es propio de C++; muestra la violación de la regla de una definición que nadie diagnostica y reúne en una lista todo el comportamiento indefinido del curso, con lo que detecta cada caso; repite en su evaluación de salida las destrezas de la entrada; propone seis desafíos que combinan la unidad; y termina con el proyecto final del curso, especificado con precisión, con su rúbrica, en cuatro etapas, cada una con una solución de referencia comprobada.

Objetivos de aprendizaje

  1. Organizar un programa en varios módulos con cabeceras, guardas y contratos, compilarlo por separado y diagnosticar los mensajes del enlazador.
  2. Probar un módulo desde su especificación, con un programa de pruebas automáticas ejecutado bajo los detectores, y comprobar con aserciones lo que no puede ocurrir.
  3. Localizar un error con un método (reproducir, reducir, formular hipótesis, bisecar) y con el depurador, y documentar la investigación.
  4. Reconocer el comportamiento indefinido que el curso ha mostrado, con lo que detecta cada caso, y la violación de la regla de una definición que nadie diagnostica.
  5. Integrar todo el curso en un proyecto: especificar, descomponer, construir, probar, medir el costo y depurar un programa de gestión de datos tabulares.

Lo logrado en la unidad

La unidad se propuso enseñar a organizar, verificar y depurar programas que ya no caben en un archivo ni en la cabeza. El propósito se ha cumplido apoyándose en lo que la introducción declaró por sabido: la declaración y la definición, la compilación y el enlace, el contrato, el invariante y la búsqueda binaria. El programa del catálogo de libros con que se abrió la unidad, que cabía en un archivo, copiaba parseInt por tercera vez y omitía en silencio «Cien años de soledad» por escribir < donde la especificación decía «ambos incluidos», se reescribe en la última sección de esta clase como proyecto final: cuatro módulos con contratos, un programa principal que responde órdenes y un programa de pruebas con veinticinco casos. Dos de esos casos, «entre, bordes» y «entre, un año», fallan con la condición del programa original, y por eso el error no volvería sin que nadie lo notara.

Varios archivos y bibliotecas propias

La clase Varios archivos y bibliotecas propias dividió un programa en una cabecera que declara, un archivo de implementación que define y un main.cpp que usa. Presentó las guardas de inclusión, que impiden la doble inclusión dentro de una unidad de traducción; la regla de una definición, que explica «multiple definition» y «undefined reference» y da a inline su sentido actual de permiso; la compilación separada con -c, que recompila solo los objetos cuyas fuentes o cabeceras cambiaron; y una biblioteca propia con funciones de clases anteriores.

Probar programas

La clase Probar programas enseñó a derivar los casos de una especificación, por regiones, bordes y casos especiales, con el resultado esperado calculado por otro camino; a escribir un programa de pruebas automáticas que informa solo los fallos y termina con código 0 o 1; a usar assert para lo que no puede ocurrir, sabiendo que -DNDEBUG lo borra con su condición; a probar al compilar con static_assert y constexpr; y a ejecutar las pruebas con los detectores. Todo descansa en la advertencia de Dijkstra: una prueba muestra la presencia de errores, nunca su ausencia.

Depurar programas

La clase Depurar programas presentó la depuración como método experimental: reproducir la falla, formular hipótesis falsables, decidir entre ellas con experimentos y bisecar el tramo sospechoso. Desarrolló el instrumento (-g sin optimización, la configuración de Visual Studio Code en los tres sistemas, una sesión real de GDB, los puntos de interrupción simples y condicionales, los pasos y la pila de llamadas) y las estrategias que valen más que él: reducir el caso, buscar el último punto correcto con aserciones y empezar por el primer marco propio del informe del detector.