Mostrando entradas con la etiqueta corrección. Mostrar todas las entradas
Mostrando entradas con la etiqueta corrección. Mostrar todas las entradas

viernes, abril 29, 2011

¿Testeo o especificaciones?

¿Cómo se determina el comportamiento de un sistema? ¿Testeo o leyes, estándares, especificaciones...? Como siempre, es mi postura, las dos. El ejemplo surge de una incialización incompleta de un array de caracteres ¿Cómo se debería comportar? Mi teoría en principio, más o menos errónea, era que debía ocurrir lo mismo que con una copia de cadenas en C. Se copia hasta el cero terminador y ahí acaba el proceso. El resto de elementos del array indefinidos, sin inicializar. Pero estaba la duda... ¿Cómo se comporta y/o se debe comportar un sistema?

Para responder a las dos preguntas ni los test son suficiente ni lo que diga el estándar lo es. Los dos juntos pueden calmar más :)

En el punto 8.5.2.3 del estándar C++0x se habla de lo que ocurre si se proporcionan menos caracteres a la inicialización:

If there are fewer initializers than there are array elements, each element not explicitly initialized shall be
zero-initialized


Sin embargo este punto está ausente en el C++98. Los test aparentemente dicen que se suelen rellenar de ceros ¿Por qué? y ¿Podemos confiar en que siempre sea así?

Asumiendo (que quizás sea mucho asumir) que la incialización de cadenas es análoga a la incialalización en forma de lista (con llaves) esto puede tener una expliación. Según se puede leer en el punto 8.5.1.7 del C++98:
If there are fewer initializers in the list than there are members in the aggregate, then each member not explicitly initialized shall be default-initialized (8.5)
[Example:
struct S { int a; char* b; int c; };
S ss = { 1, "asdf" };
initializes ss.a with 1, ss.b with "asdf", and ss.c with the value of an expression of the form
int(), that is, 0. ]



En C++0x pensaba que quizás cambia algo pero el punto 8.5.1.7 para decir básicamente lo mismo:
If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member
not explicitly initialized shall be initialized from an empty initializer list (8.5.4)

Las diferencias vienen de los mejoradas listas de inicialización de C++0x.

Leyendo todo esto yo tengo claro que no me fiaría de que el resto de los caracteres estuviesen a 0, aunque funcione así probablemente en casi todas las implementaciones... O sea, que no conviene fiarse de lo que hay después del cero terminador. Además ¿Para qué? Es tentar a la suerte...

Lecciones a aprender, al menos tal como yo lo veo:
  • Intentar no buscar los casos difíciles, en los que hay que consultar la ley. En ellos es probable que no todas las implementaciones la hayan leído correctamente
  • Conocer los estándares y especificaciones que usamos o al menos saber buscar en ellas en caso de duda
  • Testear. cuantas más pruebas se hagan al código más fácil es encontrar los "casos patológicos"

lunes, julio 23, 2007

¿Testeo o corrección?

Andaba yo descubriendo otro blog, el de Andrew Koenig, cuando, a raíz de dos post suyos seguidos (uno de aserciones contra excepciones y otro sobre la depuración) he reparado en el tema... últimamente se hace mucho hincapié en el desarrollo guiado por pruebas, pero según se puede ver en el segundo post, hay veces que las pruebas, e incluso el uso, no son garantía de corrección.

Por eso es tan importante que las pruebas sean realistas. Por eso es tan importante extraer información del sistema en todas la etapas del ciclo de vida. Por eso es tan importante un buen sistema de registro del sistema. Pero sobre todo, por eso es importante pensar bien antes de codificar.

También me ha recordado uno esos principios de desarrollo polémicos: Los fallos, cuanto antes mejor (Fail Fast). Es uno de los principios en el diseño de Erlang. Como dice Joe Armstrong en una entrevista reciente:

La filosofía de Erlang fue siempre construir sistemas con un montón de procesadores baratos y permitir que fallen. No prevenimos el fallo; vivimos con él y recuperamos el sistema cuando ocurren.

Hay que recordar que se trata de fallos irrecuperables, no de casos raros dentro de la lógica del programa. Es mejor dejar claro un error fatal que tratar de continuar cuando no se puede y que se pierda el rastro de lo sucedido...

Por supuesto el título es falaz, debería haber sido Testeo y corrección y todos contentos, pero espero que se me permita el recurso :)

¿Testeo o corrección? en barrapunto