lunes, junio 13, 2011

Un Clúster con SLURM, uso y configuración

He tenido la oportunidad de poner en marcha un clúster (pequeñito) y aprovecho que he hecho una presentación para sus usuarios para colgarla aquí por si resulta de ayuda a alguien o por si alguien la encuentra interesante.

viernes, mayo 13, 2011

Lo que todo programador de C debería saber sobre el "comportamiento indefinido"

Este ha sido uno de los artículos damnificados por la caída de blogger.com y por eso no lo he puesto aquí antes, pero me gustaría reseñar este What Every C Programmer Should Know About Undefined Behavior 1/3 del blog de LLVM. No solo hace una estupenda introducción al qué y al por qué del comportamiento indefinido en C sino que apunta a una serie de artículos que merece la pena mencionar también: A Guide to Undefined Behavior in C and C++, Part 1, Part 2 y Part 3.

Del primero de esa serie, para que quede claro de qué va el asunto :)
Of course it is physically possible to pick up a basketball and run with it. It is also possible you will get away with it during a game. However, it is against the rules; good players won’t do it and bad players won’t get away with it for long.
Como se puede leer es uno de esos temas que conviene saber (y muy bien) si se pretende hacer código portable. Así que, para leer con detenimiento.

Soy un atento seguidor del blog de LLVM, pero esta vez lo he visto en el twitter de TooManySecrets

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"