Serious programs

Leyendo esta entrada me he encontrado con la imagen siguiente, que a su vez viene de Thinking Forth:

20090222-jd6pf1gcjx77bgdh16a5ceehyc.jpg

stackoverflow.com

Últimamente, de vez en cuando y cuando el tiempo me lo permite, me paso por stackoverflow.com. Es un sitio de preguntas de programación, donde se pueden responder a las que uno sepa o bien leer las respuestas, muchas veces ingeniosas, a las preguntas de otros usuarios. Al responder, la gente puede votarte, lo que te da "reputación". Yo, con un valor actual de 743, tengo un valor muy diminuto, comparado con los 36000 del primero :) Me parece un buen punto de encuentro de programadores. Siempre puedes encontrar una utilidad/librería/entorno que no conoces, y puedes también ayudar a los demás en cuanto sepas una respuesta. En general, además, los moderadores tienen bastante tino en puntuar y en comentar las preguntas.

C++: Optimizaciones del compilador

Hoy, durante la primera reunión de la Cátedra que hemos tenido en SAES, se me ha ocurrido una idea para hacer logging de una aplicación en C++. Hace un tiempo leí en el blog de mi amigo Boris Kolpackov cómo el compilador de C++ es lo suficientemente inteligente como para darse cuenta de que cierto código no lo debe generar.

El caso del log es tal que a veces se quiere activar y otras veces desactivar de una aplicación. Cuando se desactiva para la aplicación que se entregará al usuario, cierto código de logging no tendría que aparecer (ni que ocupar tiempo) de la aplicación entregada. Sin embargo, durante el desarrollo, es interesante que el log esté activo.

Así pues, ¿cómo conseguir que el mismo código aparezca o no? La opción más común es utilizar el preprocesador para definir algún macro de depuración. Estos macros al final son algo extraños, porque utilizan el preprocesador y no objetos normales de C++, lo cual queda algo extraño y poco elegante. Viendo su artículo, se me ocurrió que se podría especializar un patrón (template) en el que la versión por defecto no hiciera nada (no hay log), y la versión activada enviaba la salida al log. He aquí una posible implementación:


#include <iostream>

class logger_base
{
public:
logger_base (std::ostream& s)
: s_ (s)
{
}

protected:
std::ostream& s_;
};

template <bool b>
class logger: public logger_base
{
public:
logger (std::ostream& s)
: logger_base (s)
{
}

template <typename T>
friend logger<b>&
operator<< (logger<b> const& l, T const& t)
{
// Default: do nothing
return const_cast<logger<b>&>(l);
}

template <typename T>
friend logger<b>&
operator<< (logger<b> const& l, char const* t)
{
// Default: do nothing
return const_cast<logger<b>&>(l);
}
};


template<>
class logger<true> : public logger_base
{
public:
logger (std::ostream& s)
: logger_base (s)
{
}

template <typename T>
friend logger<true>&
operator<< (logger<true> const& l, T const& t)
{
// Do now: log
logger<true>& _l = const_cast<logger<true>&>(l);
_l.s_ << t;
return _l;
}

template <typename T>
friend logger<true>&
operator<< (logger<true> const& l, char*const t)
{
// Do now: log
logger<true>& _l = const_cast<logger<true>&>(l);
_l.s_ << t;
return _l;
}
};

// DO LOG
typedef logger<true> logger_t;

int
main (int argc, char**argv)
{
logger_t log (std::cout);

log << "abc" << "cde";

return 0;

}


El código, primero, define un patrón que se especializa parcialmente a posteriori. Como se ha dicho, la implementación por defecto es no hacer nada. La clase logger<T> implementa el operator<< de tal forma que no hace absolutamete nada. La clase acepta cualquier std::ostream, con lo que se puede mostrar por pantalla o por cualquier fichero, socket, etc.

El código del patrón se especialza para el caso "true". Si el patrón se crea con este valor, ahora los operadores realizan la función de log de forma normal.

El usuario puede, entonces, definir el tipo logger_t como un typedef del logger adecuado, y utilizar a partir de ese momento logger_t durante todo el código.

Nótese cómo ahora no hay ningún elemento extraño ni macro más o menos afortunado. El logging se hace con streams de C++.

Ahora bien. La preunta que surge es: cuando se selecciona el patrón "false" se genera código o se elimina? Primero veamos qué genera el compilador para el caso "true" (con optimización -O2):


main:
.LFB1037:
subq $8, %rsp
.LCFI1:
movl $3, %edx
movl $.LC0, %esi
movl $_ZSt4cout, %edi
call _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
movl $3, %edx
movl $.LC1, %esi
movl $_ZSt4cout, %edi
call _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
xorl %eax, %eax
addq $8, %rsp
ret


Véase cómo el compilador reduce las llamadas inline a una llamada a ostream::insert dos veces (con las dos cadenas), y el log se produce. Ahora para el caso "false" (también con -O2):


main:
.LFB1037:
xorl %eax, %eax
ret


Esto es, el compilador no produce ningún código (el valor 0 se retorna en eax), y optimiza automáticamente todas las llamadas al log. Estos mecanismos de metaprogramación hacen a C++ todavía más potente de lo que parece a simple vista.

.





, originally uploaded by dsevilla.



Rolleiflex SL 66 + Rollei Planar HFT 80mm/2.8 + Fuji RAP 100F. Wide open.



En el restaurante de la Santa de Totana. Muy bueno, por cierto.

Más avances: Cátedra SAES-UMU

Como un avance inédito (se firma mañana), os diré que otra cosa que me ha tenido muy ocupado los últimos meses (en realidad años) es lo que hemos llamado la "Cátedra SAES-UMU". Esta cátedra significa un apoyo monetario a la investigación que una empresa privada, en este caso la Sociedad Autónoma de Electrónica Submarina (SAES), ofrece a la Universidad de Murcia a través de unos promotores de la misma (en este caso Gregorio Martínez y yo mismo). El acuerdo será por dos años, y pronto prepararemos una página web con algunos resultados que estamos obteniendo en nuestras investigaciones.

La cátedra se financia por la empresa, y permite que nosotros contratemos a personal que realiza investigaciones, tesis, etc. (camos, la labor de la Universidad), mientras que la empresa se beneficia de que orientemos nuestras investigaciones hacia temas que le sean de interés. Esta sinergia universidad-empresa es el fin último de la Universidad, que tiene que proveer conocimiento básico que finalmente se pueda aplicar a una empresa.

Personalmente estoy muy contento (y también orgulloso en cierto grado), como sé que lo está Gregorio, de que esta empresa haya confiado en nosotros para ofrecernos esta oportunidad, también teniendo en cuenta que es la cátedra de más cuantía económica que se ha realizado nunca en la Universidad de Murcia. Esta confianza mutua se ha ido fraguando a lo largo de tres años de colaboraciones puntuales con la empresa en tópicos relacionados con el modelado de aplicaciones, software libre, programación en C++, programación distribuida y CORBA (sí, chichos, por extraño que parezca), etc.

La firma la realizará el Rector de la Universidad de Murcia junto con el director general de SAES mañana miércoles 4 a las 10 de la mañana en el edificio de convalecencia de Murcia. Irá también la prensa, así que no descarto que aparezca en los periódicos.

Nada más por hoy que mañana tenemos un acto importante...

Avanzando temas: Tesis

Bueno, aquellos que me conocéis o que estáis en mi círculo más cercano sabréis que el año pasado estuve bastante ocupado, dejando a un lado casi a mis amistades, aficiones, ... todo lo que no fuera la tesis.

El trabajo de escribirla e implementarla fue inmenso para mí. Quizá otras personas tengan más facilidad o no les cause tanto estrés y cansancio, pero a mí me dejó exhausto. Tanto que cuando la terminé ya no quiero ni volver a verla.

Sí me gustaría, no obstante ir comentando poco a poco cómo la hice, los puntos importantes, y mostrar la propia tesis, que al menos, si alguien la lee, o alguna parte de ella, que al menos tenga la sensación de que sirve para algo...

La presentación de la misma fue el día 4 de noviembre, y todo fue bien. Menos mal, después de tanto trabajo. Parece que les gustó a los miembros del tribunal (que me calificaron con Summa Cum Laude por unanimidad).

Por ahora os dejo una página que hice para mostar la tesis a los miembros del tribunal. La tesis está en PDF (ojo, 64MB), y también página a página. Que la disfrutéis. Me guardo para después explicar un poco de la tesis en sí misma y de cómo la fui desarrollando.