¿Qué metodología se debe adoptar para codificar un programa C libre de errores?

Hay un gran libro sobre este tema llamado “Writing Solid Code” (http://www.microsoft.com/mspress…)

La idea básica es que cuando las cosas se complican y comienzan a ir mal, realmente necesitas una forma clara de determinar qué funciona y qué no. Y cuando algo sale mal, debe notarlo lo más cerca posible de la raíz del problema.

Aquí hay algunas sugerencias prácticas, algunas de Writing Solid Code y algunas de mi experiencia:
– Active todas las advertencias del compilador y arregle todo lo que informe.
– Si conoce un error, corríjalo antes de hacer cualquier otra cosa.
– Divida su código en pequeñas funciones que tengan entradas y salidas claras y la menor cantidad posible de efectos secundarios. Déles nombres que indiquen claramente lo que hacen.
– Escribir pruebas para cada función.
– Haga que todas las funciones verifiquen entradas y salidas razonables.
– Identifique todos los invariantes que pueda y verifíquelos con afirmaciones.
– Evita las macros si puedes. Son geniales para algunas cosas, pero si se salen de control pueden hacer que sea imposible leer el código.
– Fallo rápido: si algo no tiene sentido, no continúe con el
mejor esfuerzo y deja que se vuelva aún más extraño. Elevar un error real de inmediato
o volcar el núcleo.
– Fortifique sus subsistemas: cosas como la administración de memoria deben verificar si hay errores comunes y facilitar la inspección de lo que sucede cuando hay errores.
– Dos lugares en los que comúnmente tiene errores difíciles son la asignación de memoria y el subprocesamiento. Haga un plan claro y directo para ambos: quién posee qué memoria, cuándo y qué bloqueos cubren qué, qué subprocesos pueden adquirirlos de qué capas de código y en qué orden. Si estos se complican, tenga una forma de depurarlos, o incluso afirme mejor a los invariantes.
– Si tiene un algoritmo complicado que es difícil de probar, impleméntelo de dos maneras diferentes y compare los resultados cuando lo esté probando.

Lo más importante, haga que todo sea lo más claro y directo posible, haga una cosa a la vez en el código y haga que el código se lea lo más fielmente posible a la forma en que lo describiría en inglés a un amigo.

Bueno, como han dicho otros antes que yo, estas son formas bastante buenas de programar, pero creo que se mencionaron pocos consejos prácticos.

Es importante pensar a la defensiva y no confiar en nadie. Una función, por ejemplo, no debe confiar en sus entradas. Si eso es demasiado riguroso, o es una gran sobrecarga, puede limitar estas comprobaciones al nivel del módulo (como en OOP). Lo importante es que debe tener una zona confiable y no confiable en cada módulo y función, y al imponer estos límites puede limitar la propagación de errores y segmentar su código para que sea fácil de mantener.

En estas situaciones, me gusta pensar en las entradas como datos que se originan en fuentes de malicios, es decir, intentos de piratería. Esto me hace pensar muy a la defensiva, y por lo tanto resulta en un código cauteloso y robusto. No confiar en nada es clave para producir software con pocos defectos, por lo que está compilando con todas las advertencias habilitadas. Deshazte de estos.

También una cosa importante además de la corrupción de memoria que se menciona mucho aquí es el número entero bajo / desbordamiento, que también puede morder uno en la parte trasera. Como diría cualquier programador con mentalidad de seguridad: reduzca la superficie de ataque y no reinvente la rueda. Para una buena lectura, explore la fuente del servidor Linux ftp vsftpd. Hay algunos textos en la carpeta de documentación, y discuten este mismo tema.

Feliz codificación 🙂

Gergely – ingeniero de toptal.com

Es posible escribir código C sin errores, o más bien, escribir código a un nivel de corrección más allá de lo que muchos programadores creerían que es posible. Existe un código que, si se inspeccionara profunda y cuidadosamente, sorprendería a los programadores con la cantidad de errores que contiene.

(Por supuesto, no es posible que los humanos escriban código C absolutamente libre de errores, incluso de tamaño moderado; o que el código C “libre de errores” permanezca libre de errores bajo todos los supuestos que podrían aplicarse razonablemente al código C. )

Hay dos modelos a seguir que puede tener cuando se trata de escribir código C libre de errores: Arthur Whitney y Daniel J. Bernstein. Sus enfoques difieren ligeramente, pero lo que encontrará en común es un énfasis en probar que el código es correcto, para usted mismo, antes de escribirlo, utilizando el mismo rigor que generalmente se reserva para las pruebas matemáticas. Se acepta que los programadores informáticos que escriben software libre de errores operan con un mayor nivel de rigor que los matemáticos.

Estas son las principales pautas a seguir al escribir código libre de errores:

  1. Escribe el código como lo harías con las pruebas matemáticas
  2. Reduce el tamaño del código
  3. Prueba para eliminar errores tipográficos y errores tipográficos lógicos.

Algunas observaciones sobre cada uno de estos puntos:

1. El tema básico es que la lógica del código de computadora es una representación burda de la lógica de las matemáticas, y cuanto más respetes la estructura subyacente de las matemáticas, menos problemas tendrás, ya que las matemáticas encajan perfectamente y sin problemas. Que esto funcione es sorprendentemente poco conocido. Su oscuridad posiblemente se deba a los efectos secundarios del hecho de que los matemáticos y los ambiciosos proyectos de programación divergieron a mitad de la historia de la informática.

Que tratar la programación como matemática ruidosa es tan eficaz es difícil de demostrar y más difícil de probar. Su efectividad puede ser similar a los datos curiosos sobre las matemáticas que se encuentran en “La irrazonable efectividad de las matemáticas en las ciencias naturales” de Wigner ( http://www.dartmouth.edu/~matc/M …).

Escribir código como las matemáticas contrasta con la forma común de escribir código, que consiste en arrojar el código que, en el mejor de los casos, la esperanza puede ser correcta, y luego convertir el pensamiento incorrecto en algo que funcione principalmente, adecuándolo al código existente martillando cualquier error a medida que aparecen.

2. Hay muchos beneficios para reducir el tamaño del código. Aquí hay algunos que se aplican al código libre de errores:

  1. Impone una comprensión profunda de lo que está escribiendo.
  2. Reduce el volumen de código que debe verificarse
  3. Hace que sea más probable que elija la opción correcta, “mathy”
  4. Empíricamente, el proceso de reducción tiene una habilidad mágica para descubrir errores

3. La descarga de datos a través de su código es la forma más rápida de detectar errores persistentes. Cuando las personas dicen que un proyecto está maduro, lo que realmente dicen es que el proyecto ha existido el tiempo suficiente como para encontrar una amplia gama de casos atípicos e insumos degenerados que causan problemas al programa. Este proceso generalmente ocurre durante la larga vida de un programa grande y desordenado. En el caso de piezas matemáticas cortas y correctamente ajustadas, condensa gran parte de este proceso en las pruebas breves que realiza antes de pasar el código a producción.