<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>dacap.com.ar</title>
 <link href="http://dacap.com.ar/atom.xml" rel="self"/>
 <link href="http://dacap.com.ar"/>
 <updated>2013-03-01T11:15:40-03:00</updated>
 <id>http://dacap.com.ar</id>
 <author>
   <name>David Capello</name>
   <email>davidcapello@gmail.com</email>
 </author>

 
 <entry>
   <title>UI de un instalador</title>
   <link href="http://dacap.com.ar/blog/dev/ui-de-un-instalador"/>
   <updated>2013-02-28T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/dev/ui-de-un-instalador</id>
   <content type="html">&lt;p&gt;Intenté instalar Fedora 18. Estos son los problemas en la primera pantalla de la instalación. (Demás está decir que tuve ganas de dejar la instalación acá mismo.)&lt;/p&gt;
&lt;div class='separator' style='clear:both;text-align:center;margin:8px;'&gt;
&lt;img border='0' src='fedora-18.png' /&gt;
&lt;/div&gt;
&lt;p&gt;La primera pantalla (ver screenshot) muestra la selección de lenguaje. Una lista con todos los lenguajes, y por defecto seleccionado inglés (fair enough). Selecciono español con el mouse. No hay problemas por ahora.&lt;/p&gt;

&lt;p&gt;Debajo de la lista hay un texto box y un check box. No entiendo muy bien para qué sirve el text box, y el checkbox dice &lt;em&gt;&amp;#8220;Fijar la distribución de teclado predeterminado para el idioma seleccionado.&amp;#8221;&lt;/em&gt; (mensaje totalmente incomprensible). Generalmente cuando instalo un sistema operativo pienso &amp;#8220;seguro voy a tener que configurar el teclado&amp;#8221;. Por experiencia previa en Windows siempre hay dos cosas que configurar: idioma y teclado, después lo demás viene cocinado (o por lo menos es lo mínimo que espero).&lt;/p&gt;

&lt;p&gt;Escribo algo en el text box y resulta ser que actúa como filtro del lenguaje, como para buscar el lenguaje según escribimos. Esto tiene tres fallas (sí, tres fallas en una misma pantalla):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;El text box sirve para filtrar una lista que está encima de él, no por debajo, ¿para qué filtrar una lista que ya seleccioné con el mouse? generalmente los campos de búsqueda muestran los resultados abajo, no arriba, inclusive una lupa dentro del text box no vendría nada mal, por lo menos para saber que sirve para buscar,&lt;/li&gt;

&lt;li&gt;Al escribir el lenguaje, puse &amp;#8220;spanish&amp;#8221;, pero no aparece nada, hay que escribir &amp;#8220;español&amp;#8221; (extraño, ya que en el listado se muestra una columna con el nombre del idioma en inglés),&lt;/li&gt;

&lt;li&gt;Al intentar escribir &amp;#8220;español&amp;#8221; aparece &amp;#8220;espa;ol&amp;#8221;, porque todavía no pude configurar el teclado.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;En conclusión: tengo un text box que sirve para filtrar según el nombre del idioma, pero necesito colocar caracteres unicode que todavía no puedo ingresar porque no configuré el teclado, o sea, el text box no sirve &lt;em&gt;absolutamente&lt;/em&gt; para nada. ¡¿Quién demonios diseñó esta pantalla?!&lt;/p&gt;

&lt;p&gt;Y todavía falta el check box, que dicho sea de paso lo presioné pensando que servía para configurar el teclado. Pero después de clickear en &lt;em&gt;&amp;#8220;Continuar&amp;#8221;&lt;/em&gt; comprendí el mensaje: &lt;em&gt;&amp;#8220;Fijar el teclado predeterminado&amp;#8221;&lt;/em&gt;. &lt;em&gt;&amp;#8220;Fijar predeterminado&amp;#8221;&lt;/em&gt;. &lt;em&gt;&amp;#8220;Set/use default&amp;#8221;&lt;/em&gt;. Entonces dije &lt;em&gt;&amp;#8220;Ah claro no, no, no, yo quiero especificar mi teclado, no quiero uno por defecto&amp;#8221;&lt;/em&gt;, y luego no pude volver a la pantalla anterior (no hay botón &lt;em&gt;&amp;#8220;Volver&amp;#8221;&lt;/em&gt;). Tuve que salir de la instalación y comenzar de nuevo.&lt;/p&gt;

&lt;p&gt;A veces me preguntan &lt;em&gt;&amp;#8220;¿qué tiene de malo Linux?&amp;#8221;&lt;/em&gt;. Use Debian por más de 5 años (por línea de comandos, porque el GUI nunca me terminó de cerrar), y ya hace muchísimo tiempo volví a Windows, ¿por qué? por esta mentalidad endemoniada y retorcida que está detrás del diseño de cada simple pantalla, ventana, diálogo, botón.&lt;/p&gt;

&lt;p&gt;Si sos un programador, el entorno de Linux te puede beneficiar porque tiene las herramientas justas para programar, de fácil acceso e instalación, scripts, etc. Pero al tiempo que empieces a usar la interfaz gráfica, te va a dañar el cerebro. Vas a comenzar a creer que esas pantallas están bien diseñadas, y por lo tanto, terminarás siendo un peor programador.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>¿Capacidad ilimitada o brain overflow?</title>
   <link href="http://dacap.com.ar/blog/ideas/capacidad-ilimitada-o-brain-overflow"/>
   <updated>2012-12-02T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/capacidad-ilimitada-o-brain-overflow</id>
   <content type="html">&lt;p&gt;¿Qué nos ofrece Internet? ¿Qué le podemos dar? ¿Qué somos? ¿Somos lo que consumimos? Y si hoy hay un desborde de información, ¿no estaremos engordando de información? ¿no necesitamos ponernos a dieta?&lt;/p&gt;

&lt;p&gt;Antes de la aparición de las redes sociales era un poco más complicado publicar contenido en Internet, lo cual hacía que haya menos vías de comunicación, menos canales de información, menos distracciones, y menos gente publicando material. Ahora, el &amp;#8220;problema&amp;#8221; es que cualquiera puede publicar &amp;#8211;y republicar&amp;#8211; lo que sea. No sólo tenemos un exceso de información, sino que tenemos duplicación de información en exceso.&lt;/p&gt;

&lt;p&gt;¿Qué pasa cuando vemos una imagen? ¿O cuando escuchamos una música? ¿O leemos algo? ¿Dónde van a parar dentro nuestro? Internamente, no tenemos idea de cómo se almacenan esas imágenes en el cerebro, pero sí podemos afirmar que: si vemos algo nuevamente, con seguridad somos capaces de aseverar que ya lo vimos con anterioridad. Estamos seguros que esas imágenes están &amp;#8220;guardadas&amp;#8221; en nuestra mente. No podemos recordarlas con exactitud &amp;#8211;o tal vez no recordamos nada&amp;#8211; pero cuando la vemos nuevamente algo se activa, algo dentro nuestro que nos dice &amp;#8220;esto ya lo vi&amp;#8221;.&lt;/p&gt;

&lt;p&gt;Y aquí introduzco la parte más interesante: todo esto que nosotros vemos, esta marea de información que nos inunda, millones de imágenes que día a día siguen entrando en nuestras cabezas, ¿realmente nos sobrepasa? ¿o tenemos una capacidad ilimitada de decir &amp;#8220;esto ya lo vi&amp;#8221;?&lt;/p&gt;

&lt;p&gt;Y es una de las dos respuestas: o tenemos una capacidad infinita de recordar cosas, o nuestro cerebro, llegado su momento de la vida, no da más, sufre un &lt;em&gt;brain overflow&lt;/em&gt;&lt;sup id='fnref:1'&gt;&lt;a href='#fn:1' rel='footnote'&gt;1&lt;/a&gt;&lt;/sup&gt;, donde: 1) lo que vemos con nuestros ojos ya no entra en la cabeza &amp;#8211;no asimilamos más&amp;#8211;, o 2) el cerebro va descartando &amp;#8211;olvidando&amp;#8211; las imágenes más antiguas. Claro que existe una tercera opción: 3) nos quedamos inmediatamente ciegos y sordos.&lt;/p&gt;
&lt;div class='footnotes'&gt;&lt;hr /&gt;&lt;ol&gt;&lt;li id='fn:1'&gt;
&lt;p&gt;Haciendo alusión a un &lt;a href='http://en.wikipedia.org/wiki/Stack_overflow'&gt;stack overflow&lt;/a&gt;, que de manera simplificada es cuando una aplicación corriendo en una computadora se queda sin memoria para continuar, y la única resolución posible es matarla.&lt;/p&gt;
&lt;a href='#fnref:1' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Eternos</title>
   <link href="http://dacap.com.ar/blog/meta/eternos"/>
   <updated>2012-12-01T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/meta/eternos</id>
   <content type="html">&lt;p&gt;&lt;em&gt;&amp;#8220;¿Dónde puedo publicarlo?&amp;#8221;&lt;/em&gt;, &lt;em&gt;&amp;#8220;Necesito un blog&amp;#8221;&lt;/em&gt;, &lt;em&gt;&amp;#8220;Necesito otro blog&amp;#8221;&lt;/em&gt;. No, no necesito ningún blog. O al menos, no necesito otro. A veces pienso que el contenido que genero va a mejorar por cambiar de lugar. La realidad me demuestra que esto nunca sucede.&lt;/p&gt;

&lt;p&gt;La mayoría de gente no necesita un blog. La mayoría de gente no tiene nada importante para compartir, o que decirnos. Yo no tengo nada importante para ofrecerles. Y aún así, escribo esto. O mejor dicho, lo estoy escribiendo &amp;#8211;sí, con papel y lápiz, o papel y microfibra en este caso&amp;#8211;.&lt;/p&gt;

&lt;p&gt;Y mientras escribo, pienso, &amp;#8220;¿qué pasaría si todos los servidores se apagaran? ¿qué perderíamos? ¿qué parte como sociedad nos faltaría? ¿qué sociedad pasaríamos a ser? ¿o a volver a ser? El impacto no sería tanto. Sería más a nivel personal, si es que teníamos cosas &amp;#8220;ahí afuera&amp;#8221; en Internet. Y cuando digo &amp;#8220;cosas&amp;#8221; me refiero a material que nos costó esfuerzo creativo realizarlo.&lt;/p&gt;

&lt;p&gt;Por eso, estoy pensando que sería muy triste &amp;#8211;para uno&amp;#8211; perder su blog. Perder todo eso que escribió. A nadie más le importaría. Pero sí, cada una de esas almas perdería un poco de sí mismas, de eso que crearon y ahora no está más. Para la gente que nunca creó, la angustia sería nula. Como hacer zapping en el TV, o pasar a otro libro. &lt;em&gt;&amp;#8220;¿Ahora qué dan?&amp;#8221;&lt;/em&gt; se escucharía a continuación del apagón.&lt;/p&gt;

&lt;p&gt;Tal vez los servidores nunca exploten. Tal vez la nube llegó para quedarse. Igual, el mejor consejo que se me ocurre es: si realmente tienes algo que vale la pena compartir, escríbelo, dibújalo, grábalo, hazlo partitura. Porque en el futuro, es muy probable que sea lo único que tengamos para recordarnos que fuimos jóvenes, y soñamos, y un día nos sentamos, y escribimos en una hoja, pensando que seríamos eternos.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;Aclaración: Esto fue escrito bajo el título &amp;#8220;Nada que decir&amp;#8221;, en papel, el día 14 de noviembre del 2012 a las 19:30 hs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ayer leí &lt;a href='https://medium.com/writers-on-writing/1eb613ce9828'&gt;esto&lt;/a&gt; lo cual va un poco con este estilo de escribir en papel.&lt;/em&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Excepciones desde un destructor</title>
   <link href="http://dacap.com.ar/blog/cpp/excepciones-desde-un-destructor"/>
   <updated>2012-08-20T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/excepciones-desde-un-destructor</id>
   <content type="html">&lt;p&gt;Hace tres días, en C++Next publicaron &lt;a href='http://cpp-next.com/archive/2012/08/evil-or-just-misunderstood/'&gt;un artículo&lt;/a&gt; sobre tirar excepciones en los destructores. Hasta el mismo &lt;a href='http://cpp-next.com/archive/2012/08/evil-or-just-misunderstood/comment-page-1/#comment-1958'&gt;Herb Sutter anda por los comentarios&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para los que no saben, los destructores no deberían tirar excepciones. Y si la clase se usa en los contenedores de la STL, las excepciones en los destructores están completamente prohibidas. Por lo tanto, ya existe un consenso general en donde tirar excepciones desde un destructor es sólo una fuente de problemas.&lt;/p&gt;

&lt;p&gt;Así, ¿qué trae de nuevo el artículo? Bueno, aunque el artículo es interesante y lo recomiendo leer, básicamente no llega a nada. A tener en cuenta:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Si tiramos una excepciones en un destructor, la excepción se propaga como en cualquier otra función. Se siguen llamando los destructores de los subobjetos (variables miembro) y se libera la memoria utilizada por el objeto. La excepción se propaga hasta algún &lt;em&gt;catch&lt;/em&gt;. Aquí todo funciona bien, no quedan objetos &lt;em&gt;zombies&lt;/em&gt; ni &lt;em&gt;memory leaks&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Cuando ocurre una excepción, se destruyen los objetos que estaban en su ámbito y en todos los ámbitos hasta llegar al &lt;em&gt;catch&lt;/em&gt; (este proceso se llama &lt;em&gt;stack unwinding&lt;/em&gt;). ¿Qué ocurre si en medio de esos objetos que se están destruyendo ocurre otra excepción? Veamos el siguiente ejemplo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class A { ... }

class B {
public:
  ~B() { throw 2; }
}

int main() {
  try {
    A a;
    B b;
    throw 1;   // Comienza el stack unwinding, los destructores
               // se llamarán en orden: ~B y luego ~A, pero ~B tira
               // otra excepción
  }
  catch (...) { }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;La pregunta prevalece: ¿qué pasa en este caso donde &lt;code&gt;~B&lt;/code&gt; tira una excepción en su destrucción? ¿qué excepción continúa? ¿la primera o la segunda que generó el destructor?&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;El artículo propone pensar sobre este tema y que tal vez podríamos descartar la segunda excepción. El estándar propone resolverlo con un &lt;code&gt;terminate&lt;/code&gt; (ver §15.2 párrafo 3). Sencillamente, no se puede tirar otra excepción en medio del &lt;em&gt;stack unwinding&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;De los comentarios de Herb Sutter podemos sacar varios puntos muy concisos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Una excepción es un error dentro de una función, y un error ocurre cuando las postcondiciones de la función no se pueden cumplir.&lt;/li&gt;

&lt;li&gt;La postcondición de un destructor es que el objeto estará destruido al salir del destructor.&lt;/li&gt;

&lt;li&gt;La vida del objeto termina al momento que entramos en el destructor, es decir, la postcondición se cumplirá de cualquier modo. No podemos -en medio de un destructor- decir &lt;em&gt;&amp;#8220;eh, ok, esperen, este objeto no se puede destruir, cancelen todo, vayan para atrás&amp;#8221;&lt;/em&gt;. Esto no es posible, al salir del destructor, la memoria ya será liberada.&lt;/li&gt;

&lt;li&gt;Entonces, ¿por qué no tirar excepciones en un destructor? Porque no existe posibilidad de reintento o cancelación de la operación. Una vez que entramos al destructor el objeto será liberado de la memoria de cualquier modo.&lt;/li&gt;

&lt;li&gt;Podemos llegar a usar una función &lt;code&gt;b.close()&lt;/code&gt; en el caso que necesitemos atrapar excepciones en la liberación de recursos. El destructor podría simplemente llamar a &lt;code&gt;this-&amp;gt;close()&lt;/code&gt; y hacer un &lt;em&gt;catch&lt;/em&gt; de todas las excepciones para evitar que se propaguen.&lt;/li&gt;

&lt;li&gt;Él aclara que hubiera preferido destructores con &lt;a href='http://en.cppreference.com/w/cpp/language/noexcept_spec'&gt;noexcept&lt;/a&gt; en C++11: Un modificador de funciones que especifica que el compilador debe chequear que al destructor realmente no se le escapan excepciones.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Para divertirse un poco más con todo esto, recomiendo leer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ítem 16 &amp;#8220;Writing Exception-Safe Code&amp;#8221; en &lt;em&gt;Exceptional C++&lt;/em&gt; de Herb Sutter.&lt;/li&gt;

&lt;li&gt;Ítem 51 &amp;#8220;Destructors, deallocation, and swap never fail&amp;#8221; en &lt;em&gt;C++ Coding Standards&lt;/em&gt; de Herb Sutter y Andrei Alexandrescu.&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Sobre el tiempo</title>
   <link href="http://dacap.com.ar/blog/ideas/sobre-el-tiempo"/>
   <updated>2012-08-02T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/sobre-el-tiempo</id>
   <content type="html">&lt;p&gt;Muchas veces decimos &lt;em&gt;&amp;#8220;perdí el tiempo en tal cosa&amp;#8221;&lt;/em&gt; o &lt;em&gt;&amp;#8220;invertí el tiempo en tal otra&amp;#8221;&lt;/em&gt;. Estas expresiones dan a entender dos puntos: 1) que el tiempo tiene un valor, y 2) que nuestra vida, a medida que transcurre, va consumiendo ese tiempo, y vamos devaluándolo. Es como que, si pasamos tiempo fuera de algo &amp;#8220;constructivo&amp;#8221; (a nivel económico), le hacemos daño o quitamos valor a alguien -o a algo- superior a nosotros.&lt;/p&gt;

&lt;p&gt;Esa es la visión comercial del tiempo, y es la visión que la sociedad actual tiene acerca del tiempo. Creo que deberíamos comenzar a &amp;#8220;invertir&amp;#8221; más tiempo en pensar sobre el tiempo mismo.&lt;/p&gt;

&lt;p&gt;Personalmente, sospecho que el tiempo no se pierde, ni se gana, ni se invierte, ni desaparece. El tiempo simplemente pasa, y nosotros estamos en algún lugar, sencillamente pasando el tiempo. No hay nada ni nadie superior a quien le estemos fallando si usamos nuestro tiempo en cosas que no son vistas como &amp;#8220;productivas&amp;#8221; por los ojos de la sociedad actual.&lt;/p&gt;

&lt;p&gt;Ver una película, escuchar una música, estar tirado en la cama, usar Internet, ver televisión, escuchar la radio, leer una novela, poesía, jugar, o sentarse en la vereda, no es una pérdida de tiempo. Es una &amp;#8220;inversión&amp;#8221; del tiempo en nosotros mismos, y ese tiempo simplemente debe pasar, para llenarnos.&lt;/p&gt;

&lt;p&gt;Tal vez no nos damos cuenta que el tiempo es necesario que lo pasemos. Que no existe inversión alguna, ni pérdida. Sólo es eso, pasar el tiempo.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>La gran unificación de la programación</title>
   <link href="http://dacap.com.ar/blog/ideas/la-gran-unificacion-de-la-programacion"/>
   <updated>2012-07-18T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/la-gran-unificacion-de-la-programacion</id>
   <content type="html">&lt;p&gt;Imaginemos un mundo donde no exista código duplicado, nada. Sólo un gran repositorio con &amp;#8220;pedazos de lógica&amp;#8221; Eso significa que la más insignificante porción de lógica, por ejemplo, calcular el mínimo entre dos números, existe una única vez codificada en un lenguaje de programación universal al cual todos podemos acceder. Ejemplo en pseudo-código:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;importá &amp;quot;el código para calcular un mínimo entre dos valores&amp;quot;
         y dejalo en una función que se llame &amp;quot;min&amp;quot;
definí la variable a = min(3, 2)
devolvé a&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Así nunca nadie debería codificar nunca jamás cómo se calcula el mínimo de dos valores. Inclusive nuestro pequeño programa se podría dejar en el repositorio como &amp;#8220;el calculador del mínimo entre 3 y 2&amp;#8221;. (Completamente inútil, pero podríamos dejarlo, e inclusive, debería estar ahí, porque yo ya lo escribí aquí.)&lt;/p&gt;

&lt;p&gt;¿Cuál es el problema? Las interfaces. Por ejemplo ¿Qué requisito necesita nuestro &amp;#8220;código para calcular un mínimo&amp;#8221;? ¿Usará el operador &lt;code&gt;&amp;lt;&lt;/code&gt; para comparar los argumentos? ¿O el &lt;code&gt;&amp;gt;&lt;/code&gt;? ¿Y si usamos nuestro propio tipo de dato? ¿Podemos calcular el mínimo entre dos archivos, o documentos, o personas, o naranjas? ¿Qué devuelve &lt;code&gt;min&lt;/code&gt;, una copia de los argumentos o una referencia? Si devuelve una copia ¿cómo crea la copia? ¿qué es una referencia?&lt;/p&gt;

&lt;p&gt;Los templates de C++ resuelven muchas de estas preguntas (y los &amp;#8220;conceptos&amp;#8221; intentaban ser esta especificación de esta interfaz). Pero C++ sólo anda en C++. Lo que aquí me pongo a imaginar es un lenguaje universal, que puede ser importado y convertido a cualquier otro lenguaje y luego interpretado o compilado a lo que sea. Es decir, un repositorio de pseudo-código para resolver cualquier tipo de cuestiones.&lt;/p&gt;

&lt;p&gt;Ejemplos: Quiero un calculador de la sucesión de Fibonacci, PUM! ahí lo tenes para Fortran. Quiero una implementación de un radio button para Java, PAM! Ahí lo tenes. Quiero un Tetris andando con highscore y todo en&amp;#8230; sí, en C mandamelo, SALE CON FRITAS!&lt;/p&gt;

&lt;p&gt;¿Existirá algún día la cero duplicación de código?&lt;/p&gt;

&lt;p&gt;Publicado originalmente &lt;a href='https://plus.google.com/109465192499995663692/posts/GVGDyMjLu2o'&gt;aquí&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>La utopía de Nietzsche</title>
   <link href="http://dacap.com.ar/blog/ideas/la-utopia-de-nietzsche"/>
   <updated>2012-07-07T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/la-utopia-de-nietzsche</id>
   <content type="html">&lt;p&gt;Hace ya unos años atrás leía el siguiente aforismo de Friedrich Nietzsche de &lt;em&gt;Humano, demasiado humano&lt;/em&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;462.- Mí utopía.&lt;/strong&gt; En un mejor orden social, habrán de atribuirse las tareas pesadas y los trabajos arduos de la vida a aquél que menos sufra, es decir, al más insensible, e ir subiendo así gradualmente hasta el hombre más sensible a las formas más nobles y sublimes de dolor, a quien una vida aliviada al extremo no impedirá, entonces, que siga sufriendo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Un mundo donde todos sufren por igual.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Tipos para todo</title>
   <link href="http://dacap.com.ar/blog/cpp/tipos-para-todo"/>
   <updated>2012-07-03T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/tipos-para-todo</id>
   <content type="html">&lt;p&gt;Consejos para desarrolladores: Si un programa tiene que manejar una entidad, por más mínima que sea, no subestimes el poder que tiene crear un tipo de dato para esa entidad. Por ejemplo: un DNI (Documento Nacional de Identidad) se pueden representar con un &lt;code&gt;string&lt;/code&gt; o un entero de 64 bits, pero tal vez sea mejor usar un tipo de dato propio (ej: una clase); una coordenada X podría ser un entero, o realmente una clase &lt;code&gt;CoordenadaX&lt;/code&gt; (o un simple &lt;code&gt;typedef&lt;/code&gt; de C++ como para comenzar).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Ventajas?&lt;/strong&gt; En lenguajes de tipado estático, podemos obtener muchísimas validaciones en tiempo de compilación. Por ejemplo, validaciones del tipo &amp;#8220;aquí espero un DNI, no espero cualquier entero&amp;#8221;; o validaciones de unidades como &amp;#8220;aquí espero gramos, no un double cualquiera&amp;#8221;.&lt;/p&gt;

&lt;p&gt;No me extrañaría ver en un futuro que Java y C# adopten los &lt;a href='http://es.wikipedia.org/wiki/C%2B%2B11#Literales_definidos_por_el_usario'&gt;sufijos personalizables de C++11&lt;/a&gt;. Estos sufijos permiten hacer más sencillo definir literales de nuestro propios tipos. Ejemplos:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;DNI algunDni = 14304890_dni;
CoordenadaX posicion = 32_x;
Width ancho = 320_width;
Gramos peso = 10_kg + 500_g;
Bits datosCrudos = 10010_bits;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sí, todas son posibles expresiones de C++11 definiendo los tipos de datos correctos y sobrecargando el &lt;code&gt;operator&amp;quot;&amp;quot;&lt;/code&gt;. (Vale la pena ver la implementación del &lt;code&gt;_bits&lt;/code&gt; en esta &lt;a href='http://stackoverflow.com/a/7906630'&gt;respuesta de StackOverflow&lt;/a&gt;.)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Tools for web development</title>
   <link href="http://dacap.com.ar/blog/dev/tools-for-web-development"/>
   <updated>2012-06-23T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/dev/tools-for-web-development</id>
   <content type="html">&lt;p&gt;This is a set of tools, projects, libraries, frameworks, etc. to create web applications that I recommend you to check out. I&amp;#8217;ll be modifying this list if I found more and more libraries. Feel free to recommend one in the comments section below.&lt;/p&gt;

&lt;h3 id='application_logic_at_client_side'&gt;Application logic at client side&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://jquery.com/'&gt;jQuery&lt;/a&gt;: jQuery gives you an easy and portable way to query for DOM elements, create AJAX requests, create animation, etc. It&amp;#8217;s like the &lt;em&gt;de facto&lt;/em&gt; framework to extend JavaScript. There are others like &lt;a href='http://script.aculo.us/'&gt;script.aculo.us&lt;/a&gt;, &lt;a href='http://mootools.net/'&gt;mootools&lt;/a&gt;, etc.&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/wycats/handlebars.js'&gt;Handlebars.js&lt;/a&gt;: Templating engine at client side. You can render JSON objects to HTML.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='style_html_organization_and_ui_helpers'&gt;Style, HTML organization, and UI helpers&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://twitter.github.com/bootstrap/'&gt;Twitter Bootstrap&lt;/a&gt;: All your website style should be based on this. Forget your way to layout HTML elements and CSS style, this is the &lt;em&gt;right way&lt;/em&gt; to do it.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://lesscss.org/'&gt;less&lt;/a&gt;: A dynamic stylesheet language. Useful to avoid duplicating colors/styles all over a CSS file.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://jqueryui.com/'&gt;jQuery UI&lt;/a&gt;: UI widgets and extensions to build really interactive pages with JavaScript and jQuery.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://layout.jquery-dev.net/'&gt;jQuery UI Layout&lt;/a&gt;: A way to organize your page like a desktop app with docking panes. &lt;a href='http://layout.jquery-dev.net/demos/example.html'&gt;Example&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://fancybox.net/'&gt;fancybox&lt;/a&gt;: A library to show screenshots with fancy transitions (depends on jQuery).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='data_visualization'&gt;Data visualization&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='https://github.com/mleibman/SlickGrid/wiki'&gt;SlickGrid&lt;/a&gt;: A super customizable open source JavaScript grid to display &lt;em&gt;a lot&lt;/em&gt; of data. You&amp;#8217;ll need JavaScript knowledge to customize this grid, but it feels really good when you found a bug and you can fix it (also you can send &lt;a href='https://github.com/mleibman/SlickGrid/pulls'&gt;pull requests&lt;/a&gt; to the author). &lt;a href='http://grooveshark.com/'&gt;Grooveshark&lt;/a&gt; uses this grid.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://dygraphs.com/'&gt;dygraphs&lt;/a&gt;: Create zoomable charts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='webfonts__icons'&gt;WebFonts &amp;amp; Icons&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://www.theleagueofmoveabletype.com/'&gt;The League of Moveable Type&lt;/a&gt;: Open web fonts.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://fortawesome.github.com/Font-Awesome/'&gt;Font Awesome&lt;/a&gt;: A web font where each glyph is an icon.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.codefear.com/graphics/20-free-black-white-icon-sets/'&gt;Black &amp;amp; White Icons&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Entrando a otro mundo</title>
   <link href="http://dacap.com.ar/blog/music/entrando-a-otro-mundo"/>
   <updated>2012-05-09T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/music/entrando-a-otro-mundo</id>
   <content type="html">&lt;div&gt;
  &lt;script src='/files/audio-player/audio-player.js' type='text/javascript'&gt;
  &lt;/script&gt;
  &lt;script type='text/javascript'&gt;
    AudioPlayer.setup(&quot;/files/audio-player/player.swf&quot;);
  &lt;/script&gt;
  &lt;div id='mp3audio'&gt;
  &lt;/div&gt;
  &lt;script type='text/javascript'&gt;
    AudioPlayer.embed(&quot;mp3audio&quot;, { soundFile: &quot;entrando_a_otro_mundo.mp3&quot;, width: 290 });
  &lt;/script&gt;
&lt;/div&gt;&lt;div class='separator' style='text-align:center;clear:both;'&gt;
&lt;a href='ojo.png'&gt;&lt;img border='0' src='ojo.png' /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Forward declarations de enumerados</title>
   <link href="http://dacap.com.ar/blog/cpp/forward-declarations-de-enumerados"/>
   <updated>2012-04-10T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/forward-declarations-de-enumerados</id>
   <content type="html">&lt;p&gt;Continuando las discusiones con los &lt;a href='https://plus.google.com/u/0/b/111182086636270314265/111182086636270314265/posts/hk7tonfPkFj'&gt;forward declarations&lt;/a&gt;, podemos destacar un pequeño tipo de dato que nunca tuvo esta capacidad, por lo menos no hasta C++11: Los &lt;em&gt;enum&lt;/em&gt;erados.&lt;/p&gt;

&lt;p&gt;Los &lt;em&gt;enum&lt;/em&gt; siempre fueron un problema en la definición de APIs. Actualmente, si queremos usar un enumerado en una función o como miembro de una clase, debemos tener su definición completa con anterioridad, inclusive el listado de valores posibles que puede tomar el enumerado.&lt;/p&gt;

&lt;p&gt;Esto es muy sencillo de ver en el siguiente ejemplo. Imaginemos que nuestro programa se comunica con el usuario por medio de una GUI (ventanas, botones, controles de todo tipo). Cada control puede recibir mensajes desde el sistema operativo, por ejemplo, si el usuario clickea un botón, tiene sentido que recibamos el mensaje &lt;code&gt;BotonMousePresionado&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Aquí un enumerado con el listado de posibles mensajes que podemos recibir (imaginemos esto en un archivo &lt;code&gt;tipo_mensaje.h&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;enum TipoMensaje {
  AbrirVentana,
  CerrarVentana,
  BotonMousePresionado,
  TeclaPresionada
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;En el caso de que declaremos una clase que utiliza el enumerado, necesitamos de la definición de &lt;code&gt;TipoMensaje&lt;/code&gt; completa:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#include &amp;quot;tipo_mensaje.h&amp;quot;   // Necesitamos la definición del enumerado

class Mensaje {
  TipoMensaje mensaje;
public:
  // ...
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Inclusive aunque no utilicemos los valores posibles del enumerado, no hay forma de desacoplarlo. Esto se debe a que según el estándar de C++, la cantidad de memoria usada por un enumerado depende de la implementación del compilador y del rango de valores permitidos del enumerado. Ejemplo: Un compilador podría decidir usar un &lt;code&gt;char&lt;/code&gt; en vez de un &lt;code&gt;int&lt;/code&gt; para representar nuestro &lt;code&gt;TipoMensaje&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cuál es la desventaja?&lt;/strong&gt;&lt;br /&gt; Debido a que el compilador decide, según reglas internas y los valores posibles del &lt;em&gt;enum&lt;/em&gt;, qué tipo de dato usar para representarlo, cada vez que agreguemos un nuevo valor al enumerado debemos recompilar todos los archivos que lo estaban referenciando.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cómo podemos solucionarlo?&lt;/strong&gt;&lt;br /&gt; C++11 introduce el concepto de los &amp;#8220;enumerados fuertemente tipados&amp;#8221; (strongly typed enumerations). Con lo cual podemos decidir qué tamaño específico tiene el enumerado.&lt;/p&gt;

&lt;p&gt;Si conocemos con anterioridad cuántos valores queremos codificar en nuestro &lt;em&gt;enum&lt;/em&gt;, podemos especificar la cantidad de memoria requerida por el mismo. Podemos definir un enumerado que ocupe sólo 8 bits:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;enum TipoMensaje : char {
  AbrirVentana,
  CerrarVentana,
  BotonMousePresionado,
  TeclaPresionada
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Y si necesitamos referenciarlo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;enum TipoMensaje : char;    // Forward declaration

class Mensaje {
  TipoMensaje mensaje;
public:
  // ...
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;¿Por qué se llaman &amp;#8220;enumerados fuertemente tipados&amp;#8221;?&lt;/strong&gt;&lt;br /&gt; Ese es otro tema que lo dejo para un próximo post.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Referencias: &lt;a href='http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf'&gt;N2347&lt;/a&gt; (pdf)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Reformat XML on Emacs</title>
   <link href="http://dacap.com.ar/blog/emacs/reformat-xml-on-emacs"/>
   <updated>2012-04-09T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/emacs/reformat-xml-on-emacs</id>
   <content type="html">&lt;p&gt;You can reformat XML code adding the following code in your .emacs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(require &amp;#39;sgml-mode)

(defun reformat-xml ()
  (interactive)
  (save-excursion
    (sgml-pretty-print (point-min) (point-max))
    (indent-region (point-min) (point-max))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And executing &lt;code&gt;reformat-xml&lt;/code&gt; in your XML buffer then.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Paréntesis en una URL</title>
   <link href="http://dacap.com.ar/blog/dev/parentesis-en-una-url"/>
   <updated>2012-04-08T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/dev/parentesis-en-una-url</id>
   <content type="html">&lt;p&gt;Ya van dos veces que tengo que buscar cómo se codifican los paréntesis en una URL. Aquí dejo esto como futura referencia:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El paréntesis de apertura ( se puede escribir como %28&lt;/li&gt;

&lt;li&gt;El paréntesis de cierre ) se puede escribir %29&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ejemplo: Un link a &lt;code&gt;http://en.wikipedia.org/wiki/Tee_(command)&lt;/code&gt; se puede escribir como &lt;code&gt;http://en.wikipedia.org/wiki/Tee_%28command%29&lt;/code&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Game concepts</title>
   <link href="http://dacap.com.ar/blog/gamedev/game-concepts"/>
   <updated>2012-04-05T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/gamedev/game-concepts</id>
   <content type="html">&lt;p&gt;These are several (maybe unimplementable) game concepts that I&amp;#8217;ll be releasing in my &lt;a href='http://twitter.com/davidcapello/'&gt;Twitter account&lt;/a&gt; and adding them here frequently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid to bite your tongue. &lt;a href='https://twitter.com/#!/davidcapello/status/187705018114248704'&gt;tweet&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Social Network Tycoon, you&amp;#8217;ve to create and maintain your own social network, destroying the competition. &lt;a href='https://twitter.com/#!/davidcapello/status/187894104837988352'&gt;tweet&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Prepare as many &lt;a href='http://en.wikipedia.org/wiki/Mate_%28beverage%29'&gt;mates&lt;/a&gt; as you can before it became washed out. &lt;a href='https://twitter.com/#!/davidcapello/status/188373968632291328'&gt;tweet&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Drink as much beer as you can without getting drunk. &lt;a href='https://twitter.com/#!/davidcapello/status/188835537208094720'&gt;tweet&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;You are a book and you must find your writer&amp;#8230; because you&amp;#8217;ve a typo. &lt;a href='https://twitter.com/davidcapello/status/205112884160765952'&gt;tweet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Una cosa por vez</title>
   <link href="http://dacap.com.ar/blog/productividad/una-cosa-por-vez"/>
   <updated>2012-04-04T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/productividad/una-cosa-por-vez</id>
   <content type="html">&lt;p&gt;Hoy leí el siguiente artículo: &lt;a href='http://blogs.hbr.org/schwartz/2012/03/the-magic-of-doing-one-thing-a.html'&gt;The Magic of Doing One Thing at a Time&lt;/a&gt; (&lt;em&gt;La Magia de Hacer Una Cosa a la Vez&lt;/em&gt;). Más allá de los consejos específicos para un &lt;em&gt;manager&lt;/em&gt; o individuos en la empresa, quiero resumir los puntos importantes en general para cualquier ser humano.&lt;/p&gt;

&lt;p&gt;Prácticamente, si te sentis abrumado por millones de tareas en el trabajo e información que te llega de todos lados, podes tomar las siguientes estrategias para aumentar tu productividad, o mejor dicho, volverla a su estado natural antes de que este mundo enfermo llegara:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;No juegues a la multi-tarea. No hagas malabares con todo. Dedicate a resolver una tarea por vez y bien.&lt;/li&gt;

&lt;li&gt;Pequeños tiempos muertos también ayuda. No intentes &amp;#8220;rellenar&amp;#8221; esos tiempos haciendo otras pequeñas tareas.&lt;/li&gt;

&lt;li&gt;Si tenes un teléfono &amp;#8220;inteligente&amp;#8221;, apagalo el mayor tiempo posible (o quemalo y comprate un celular normal).&lt;/li&gt;

&lt;li&gt;No esperes respuesta inmediata de todos. Así tampoco interrumpís el trabajo de los demás.&lt;/li&gt;

&lt;li&gt;Hace la cosa más importante al inicio de la mañana, a la primera hora (sin interrupciones ni distracciones).&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>Lenguaje</title>
   <link href="http://dacap.com.ar/blog/meta/lenguaje"/>
   <updated>2012-03-23T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/meta/lenguaje</id>
   <content type="html">&lt;h3 id='cmo_elijo_que_una_pgina_este_en_ingls_o_espaol'&gt;¿Cómo elijo que una página este en inglés o español?&lt;/h3&gt;

&lt;p&gt;Este sitio contiene páginas que están en español y otras que están en inglés. Generalmente no podrá encontrar la misma página traducida en ambos lenguajes. Y en esta etapa de mi vida, muy difícilmente me dedicaré a traducir todo lo que escribo.&lt;/p&gt;

&lt;p&gt;Dependiendo de lo que quiero transmitir, una página estará en un lenguaje u otro. Si quiero publicar una aplicación o un juego, probablemente lo haga en inglés. Si en cambio quiero transmitir una idea, lo haré en mi lengua materna, español.&lt;/p&gt;

&lt;h3 id='por_qu'&gt;¿Por qué?&lt;/h3&gt;

&lt;p&gt;Prefiero no traducir nada. No soy tan bueno escribiendo inglés como me gustaría y todavía tengo que aprender a escribir en español.&lt;/p&gt;

&lt;p&gt;Si vale la pena transmitir una idea compleja correctamente, utilizaré español, en caso contrario, utilizaré inglés. Inclusive, le recomiendo hacer lo mismo. Se disfruta más escribiendo y leyendo en la lengua de uno antes que en la ajena, es más sencillo expresar ideas y es probable que contenga &lt;em&gt;menos&lt;/em&gt; errores.&lt;/p&gt;

&lt;p&gt;Y como punto adicional: prefiero comunicarme y discutir con gente que entienda mi lengua.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>iosfwd</title>
   <link href="http://dacap.com.ar/blog/cpp/iosfwd"/>
   <updated>2012-02-24T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/iosfwd</id>
   <content type="html">&lt;div class='post'&gt;
La librería estándar de C++ ofrece un archivo de cabecera de &lt;a href=&quot;https://plus.google.com/u/0/b/111182086636270314265/111182086636270314265/posts/hk7tonfPkFj&quot;&gt;forward declarations&lt;/a&gt; de las clases de entrada y salida a flujos de bytes (iostreams):&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iosfwd&amp;gt;&lt;br /&gt;&lt;/pre&gt;De esta forma podemos utilizar los tipos ostream, istream, etc. sin necesidad de traer la definición de todas las clases de entrada y salida. Generalmente deberíamos utilizar el &lt;a href=&quot;http://stdcxx.apache.org/doc/stdlibref/iosfwd-h.html&quot;&gt;&amp;lt;iosfwd&amp;gt;&lt;/a&gt; en nuestro .h cuando no hagamos un mayor uso que sólo referenciarlas. Un ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;﻿#ifndef EMPLEADO_IO_H&lt;br /&gt;﻿#define EMPLEADO_IO_H&lt;br /&gt;&lt;br /&gt;#include &amp;lt;iosfwd&amp;gt; // forward declaration de ostream&lt;br /&gt;&lt;br /&gt;class Empleado;    // forward declaration de nuestro tipo&lt;br /&gt;&lt;br /&gt;// Aquí no necesitamos conocer el tamaño ni de Empleado,&lt;br /&gt;// ni de ostream, podemos compilar sólo con sus forward&lt;br /&gt;// declarations.&lt;br /&gt;void write_empleado_en_formato_binario(const Empleado&amp;amp;, ostream&amp;amp;);&lt;br /&gt;&lt;br /&gt;#endif&lt;/pre&gt;&lt;b&gt;Regla:&lt;/b&gt; Siempre intenta usar las &lt;i&gt;forward declarations&lt;/i&gt; antes que incluir los archivos de cabecera que definen las clases, los cuales suelen mostrar detalles de implementación que son propensos a cambiar. Siguiendo esta regla mejoraremos el tiempo de compilación y la cantidad de archivos a compilar al realizar una modificación en un .h.&lt;p&gt;Para más información, ver la sección 27.3 Forward declarations [iostream.forward] del &lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf&quot;&gt;último borrador público&lt;/a&gt; del estándar de C++
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Año nuevo</title>
   <link href="http://dacap.com.ar/blog/cpp/anio-nuevo"/>
   <updated>2011-12-23T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/anio-nuevo</id>
   <content type="html">&lt;div class='post'&gt;
Bueno, este año fue poco productivo en este blog. El próximo no prometo mucho más, pero espero mejorar. Dejo un par de links que agregué en la sidebar:&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://sourceforge.net/apps/mediawiki/predef/index.php?title=Main_Page&quot;&gt;Pre-defined C/C++ Compiler Macros&lt;/a&gt;: Si alguna vez tenemos que detectar la versión de un compilador o en qué plataformas estamos, estas macros pueden ayudarnos a escribir código portable.&lt;li&gt;&lt;a href=&quot;http://en.cppreference.com/w/cpp&quot;&gt;C++ Reference Wiki&lt;/a&gt;: Una wiki con referencia sobre C++ y C++11&lt;/ul&gt;Los próximos años pueden llegar a ser los mejores años de C++. Con &lt;a href=&quot;http://clang.llvm.org/&quot;&gt;clang&lt;/a&gt; avanzando sobre &lt;a href=&quot;http://gcc.gnu.org/&quot;&gt;gcc&lt;/a&gt;, es probable que aparezcan herramientas muy importantes para ayudar a programar en C++. Aquí les dejo un video:&lt;p&gt;&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;http://www.youtube.com/embed/mVbDzTM21BQ&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;p&gt;¡Feliz año nuevo!
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Ecos de la nada</title>
   <link href="http://dacap.com.ar/blog/music/ecos-de-la-nada"/>
   <updated>2011-12-12T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/music/ecos-de-la-nada</id>
   <content type="html">&lt;pre&gt;&lt;code&gt;Como el recuerdo melancólico
de un amor que nunca fue,
los ecos retumban.
Y el sonido percibido,
es un silencio atroz.&lt;/code&gt;&lt;/pre&gt;
&lt;iframe allowfullscreen='' frameborder='0' height='315' src='http://www.youtube.com/embed/o3VDdjhc-WY' width='420'&gt;
&lt;/iframe&gt;</content>
 </entry>
 
 <entry>
   <title>Una sociedad que no fue</title>
   <link href="http://dacap.com.ar/blog/ideas/una-sociedad-que-no-fue"/>
   <updated>2011-11-30T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/una-sociedad-que-no-fue</id>
   <content type="html">&lt;p&gt;No existe el dinero. No existen ricos, ni pobres. Todos trabajan, aprenden y juegan. Todos ayudan a todos. Algunos trabajan en cosas que les gusta. Otros trabajan obligados realizando tareas que nadie desea. No existen los sueldos. Se comercia con tiempo. A peores trabajos mayor el tiempo para aprender y jugar. Cualquiera puede escribir, componer, leer, escuchar, o ver una película. Todos pueden cumplir sus sueños, pero un tiempo lo tenes que donar.&lt;/p&gt;

&lt;p&gt;No existe la publicidad, ni dos productos que sirvan para el mismo fin. Los bienes materiales sirven sólo para lo que fueron creados, con el diseño que produzca el menor impacto ambiental. La comida es la mejor para la salud. Se consume todo lo que se fabrica. Se fabrica sólo lo que se necesita.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Código C++ moderno</title>
   <link href="http://dacap.com.ar/blog/cpp/codigo-cpp-moderno"/>
   <updated>2011-09-21T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/codigo-cpp-moderno</id>
   <content type="html">&lt;div class='post'&gt;
Una excelente charla de Herb Sutter&amp;nbsp;(en inglés)&amp;nbsp;introduciendo algunas de las novedades del nuevo&amp;nbsp;estándar&amp;nbsp;C++11 y sobre cómo escribir código en C++ aprovechando todo el conocimiento acumulado en estos años (si nunca leíste &lt;a href=&quot;http://www.gotw.ca/publications/c++cs.htm&quot;&gt;C++ Coding Standards&lt;/a&gt; de Herb Sutter y Andrei Alexandrescu, compralo):&lt;br /&gt;&lt;blockquote&gt;&lt;a href=&quot;http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-835T&quot;&gt;http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-835T&lt;/a&gt;&lt;/blockquote&gt;Los puntos tratados que no podes dejar pasar por alto:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;El nuevo significado de la palabra &lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B11#Type_inference&quot;&gt;auto&lt;/a&gt;&amp;nbsp;para inferir tipos automáticamente.&lt;/li&gt;&lt;li&gt;La nueva sintaxis de&amp;nbsp;&lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions&quot;&gt;lambdas&lt;/a&gt;&amp;nbsp;para definir functors en línea y usarlos en algoritmos estándares (ej: for_each()).&lt;/li&gt;&lt;li&gt;&lt;i&gt;Exception safety&lt;/i&gt; y &lt;i&gt;heap lifetime&lt;/i&gt; con&amp;nbsp;&lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B11#General-purpose_smart_pointers&quot;&gt;smart pointers&lt;/a&gt;, los cuales ya tenemos varios posts en este mismo blog sobre el concepto de smart pointers y &lt;a href=&quot;http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization&quot;&gt;RAII&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Nuevos contenedores de tipo &lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B11#Hash_tables&quot;&gt;hash table&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B11#Rvalue_references_and_move_constructors&quot;&gt;Move semantics&lt;/a&gt;&amp;nbsp;que evita la creación y destrucción de objetos temporales innecesarias (ej: al retornar por valor).&lt;/li&gt;&lt;li&gt;Varios pequeños nuevos coding standards de C++11: funciones begin()/end(), &lt;i&gt;override&lt;/i&gt; explícito, idioma pimpl con unique_ptr&amp;lt;&amp;gt;, etc.&lt;/li&gt;&lt;/ul&gt;En futuros posts voy a dedicar algo de tiempo en introducir estos temas y explicar por qué nacieron cada una de estas modificaciones en el nuevo estándar de C++.
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>El Hombre De Múltiples Caras</title>
   <link href="http://dacap.com.ar/blog/music/el-hombre-de-multiples-caras"/>
   <updated>2011-09-12T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/music/el-hombre-de-multiples-caras</id>
   <content type="html">&lt;div class='separator' style='clear: both; text-align: center;'&gt;
&lt;img border='0' height='640' src='elhombredemultiplescaras.png' width='328' /&gt;
&lt;/div&gt;&lt;div&gt;
  &lt;script src='/files/audio-player/audio-player.js' type='text/javascript'&gt;
  &lt;/script&gt;
  &lt;script type='text/javascript'&gt;
    AudioPlayer.setup(&quot;/files/audio-player/player.swf&quot;);
  &lt;/script&gt;
  &lt;div id='mp3audio'&gt;
  &lt;/div&gt;
  &lt;script type='text/javascript'&gt;
    AudioPlayer.embed(&quot;mp3audio&quot;, { soundFile: &quot;http://dacap.com.ar/files/blog/ElHombreDeMultiplesCaras.mp3&quot;, width: 290 });
  &lt;/script&gt;
&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Change volume with mouse wheel over task bar</title>
   <link href="http://dacap.com.ar/blog/tips/change-volume-with-mouse-wheel-over-task-bar"/>
   <updated>2011-08-01T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/tips/change-volume-with-mouse-wheel-over-task-bar</id>
   <content type="html">&lt;p&gt;Yeah, you can change the volume just moving the mouse wheel over task bar using &lt;a href='http://www.autohotkey.com/'&gt;AutoHotkey&lt;/a&gt; and the following little script:&lt;/p&gt;
&lt;div&gt;&lt;script src='https://gist.github.com/1119346.js?file=MouseWheelVolume.ahk'&gt; &lt;/script&gt;
&lt;noscript&gt;&lt;pre&gt;&lt;code&gt;#If MouseIsOver(&amp;quot;ahk_class Shell_TrayWnd&amp;quot;)
WheelUp::Send {Volume_Up}
WheelDown::Send {Volume_Down}

MouseIsOver(WinTitle) {
    MouseGetPos,,, Win
    return WinExist(WinTitle . &amp;quot; ahk_id &amp;quot; . Win)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/noscript&gt;&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Assault Rigs y Herbie Hancock</title>
   <link href="http://dacap.com.ar/blog/games/assault-rigs-y-herbie-hancock"/>
   <updated>2011-07-10T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/games/assault-rigs-y-herbie-hancock</id>
   <content type="html">&lt;p&gt;Hace ya unos cuantos años atrás (tal vez más de 10), cuando junto con mis hermanos adquirimos una PlayStation, la consola traía un CD de demo &lt;sup id='fnref:1'&gt;&lt;a href='#fn:1' rel='footnote'&gt;1&lt;/a&gt;&lt;/sup&gt; con varios juegos. Entre esos había uno de tanques con una música algo especial. Luego nunca más me acordé del nombre del juego, y la músico quedó perdida en mi inconsciente.&lt;/p&gt;

&lt;p&gt;Da la casualidad que ayer escuché &lt;a href='http://www.youtube.com/watch?v=Lqtki6I-VTY'&gt;Hang Up Your Hang Ups de Herbie Hancock&lt;/a&gt;. E inmediatamente recordé la música. Busqué el nombre del CD demo, encontré el listado de juegos y ahí estaba, el &lt;a href='http://en.wikipedia.org/wiki/Assault_Rigs'&gt;Assault Rigs&lt;/a&gt;:&lt;/p&gt;
&lt;iframe allowfullscreen='' frameborder='0' height='349' src='http://www.youtube.com/embed/L7dVLejDMwI' width='425'&gt;
&lt;/iframe&gt;
&lt;p&gt;La lista de músicos de Assault Rigs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Andrew Crowley&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.stuartduffield.com/Listen.html'&gt;Stuart Duffield&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/Matt_Furniss'&gt;Matt Furniss&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class='footnotes'&gt;&lt;hr /&gt;&lt;ol&gt;&lt;li id='fn:1'&gt;
&lt;p&gt;Buscar por &amp;#8220;CD Sampler Pack Vol2&amp;#8221; &lt;a href='http://www.vidgames.com/ps/software/demodisks.html'&gt;aquí&lt;/a&gt;.&lt;/p&gt;
&lt;a href='#fnref:1' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Víctima de la modernidad</title>
   <link href="http://dacap.com.ar/blog/ideas/victima-de-la-modernidad"/>
   <updated>2011-06-29T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/victima-de-la-modernidad</id>
   <content type="html">&lt;div class='separator' style='clear: both; text-align: center;'&gt;
&lt;img border='0' src='nofaceviciousman.png' /&gt;
&lt;/div&gt;
&lt;p&gt;Somos rehenes de un mundo que no hicimos. Sufrimos insomnio por una pesadilla que no soñamos. Somos partícipes de una historia que nadie recuerda. Somos guionistas de un papel protagónico que nadie actúa. Somos engranajes en un plan de unos pocos cerebros siniestros. Somos un eslabón de una cadena trunca. Somos el eco que ya no se escucha. Somos la imagen de un ruido perdido.&lt;/p&gt;

&lt;p&gt;Somos víctimas de un mundo moderno que sólo fábrica para un futuro en el que no estamos.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>One Leg</title>
   <link href="http://dacap.com.ar/blog/music/one-leg"/>
   <updated>2011-05-10T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/music/one-leg</id>
   <content type="html">&lt;div&gt;
  &lt;script src='/files/audio-player/audio-player.js' type='text/javascript'&gt;
  &lt;/script&gt;
  &lt;script type='text/javascript'&gt;
    AudioPlayer.setup(&quot;/files/audio-player/player.swf&quot;);
  &lt;/script&gt;
  &lt;div id='mp3audio'&gt;
  &lt;/div&gt;
  &lt;script type='text/javascript'&gt;
    AudioPlayer.embed(&quot;mp3audio&quot;, { soundFile: &quot;http://dacap.com.ar/files/blog/OneLeg.mp3&quot;, width: 290 });
  &lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;Short music with a couple of guitars.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Google Chrome - Always on top</title>
   <link href="http://dacap.com.ar/blog/tips/google-chrome-always-on-top"/>
   <updated>2011-03-27T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/tips/google-chrome-always-on-top</id>
   <content type="html">&lt;p&gt;OK, Google Chrome needs an &amp;#8220;Always on top&amp;#8221; option for Windows (indeed Windows needs that option for all applications).&lt;/p&gt;

&lt;p&gt;Installing &lt;a href='http://www.autohotkey.com/'&gt;AutoHotKey&lt;/a&gt; and &lt;a href='https://gist.github.com/raw/889748/30b2d013a07cc9601f7236467467caf50fc9eb74/AlwaysOnTop.ahk'&gt;running this AutoHotKey script&lt;/a&gt;, you will be able to put any window on top (with 80% of opacity) pressing just WinKey+O key when you&amp;#8217;ve the window active. Here is the script just for reference:&lt;/p&gt;
&lt;div&gt;&lt;script src='https://gist.github.com/1470122.js?file=AlwaysOnTop.ahk'&gt; &lt;/script&gt;
&lt;noscript&gt;&lt;pre&gt;&lt;code&gt;#o::
WinSet, Alwaysontop, , A

WinGet, ExStyle, ExStyle, A
if (ExStyle &amp;amp; 0x8)  ; 0x8 is WS_EX_TOPMOST
{
  WinSet, Transparent, 204, A
}
else
{
  WinSet, Transparent, 255, A
}
return
&lt;/code&gt;&lt;/pre&gt;&lt;/noscript&gt;&lt;/div&gt;
&lt;p&gt;Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can change &lt;code&gt;#o::&lt;/code&gt; in the first line with other key if you want (e.g. &lt;code&gt;#g::&lt;/code&gt; will be WinKey+G key instead of WinKey+O)&lt;/li&gt;

&lt;li&gt;You can change 204 with other level of opacity (0 is completely transparent, 255 is completely opaque)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://www.google.com/support/forum/p/Chrome/thread?tid=70d20b6ecc8110ed&amp;amp;hl=en'&gt;Request about &amp;#8220;Always on top&amp;#8221; in Google Chrome forums&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.labnol.org/software/tutorials/keep-window-always-on-top/5213/'&gt;Always on top with AutoHotKey&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Slow Walk</title>
   <link href="http://dacap.com.ar/blog/music/slow-walk"/>
   <updated>2011-03-21T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/music/slow-walk</id>
   <content type="html">&lt;p&gt;Hace mucho que no cuelgo una música, vamos con algo simple:&lt;/p&gt;
&lt;div&gt;
  &lt;script src='/files/audio-player/audio-player.js' type='text/javascript'&gt;
  &lt;/script&gt;
  &lt;script type='text/javascript'&gt;
    AudioPlayer.setup(&quot;/files/audio-player/player.swf&quot;);
  &lt;/script&gt;
  &lt;div id='mp3audio'&gt;
  &lt;/div&gt;
  &lt;script type='text/javascript'&gt;
    AudioPlayer.embed(&quot;mp3audio&quot;, { soundFile: &quot;http://dacap.com.ar/files/blog/SlowWalk.mp3&quot;, width: 290 });
  &lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;Sucesión de 12 compases clásica de blues en mi tonalidad preferida del piano (la más fácil), Do mayor. La improvisación del punteo con escala pentatónica de Do mayor.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Cola de prioridades (STL priority_queue)</title>
   <link href="http://dacap.com.ar/blog/cpp/cola-de-prioridades-stl-priority-queue"/>
   <updated>2011-03-08T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/cola-de-prioridades-stl-priority-queue</id>
   <content type="html">&lt;div class='post'&gt;
La cola de prioridades es una estructura de datos que se puede visualizar como una bolsa, donde podemos ir metiendo elementos uno atrás del otro, pero sólo los podemos retirar según un criterio de prioridad. Por ejemplo, en el caso de un ladrón obsesivo-compulsivo, podría robar un banco cargando bolsas de dinero sin ningún criterio, y al vaciarla podría retirar los billetes según su valor (primero los de $100, luego los de $50, etc.).&lt;br /&gt;&lt;br /&gt;Otro ejemplo, imaginemos que tenemos un barco:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;queue&amp;gt;&lt;br /&gt;#include &amp;lt;list&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Barco {&lt;br /&gt;public:&lt;br /&gt;  void subirPasajero(const Pasajero&amp; pasajero);&lt;br /&gt;  void abandonarBarco(list&amp;lt;Pasajero&amp;gt;&amp;amp; pasajerosEnOrden);&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;  priority_queue&amp;lt;Pasajero&amp;gt; pasajeros_;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;La función subirPasajero() debe agregar un pasajero al barco, y abandonarBarco() debe sacar todos los pasajeros del barco y colocarlos (por orden de prioridad) en la lista que se recibe como argumento:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;void Barco::subirPasajero(const Pasajero&amp;amp; pasajero)&lt;br /&gt;{&lt;br /&gt;  pasajeros_.push(pasajero);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Barco::abandonarBarco(list&amp;lt;Pasajero&amp;gt;&amp;amp; pasajerosEnOrden)&lt;br /&gt;{&lt;br /&gt;  while (!pasajeros_.empty()) {&lt;br /&gt;    pasajerosEnOrden.push_back(pasajeros_.top());&lt;br /&gt;    pasajeros_.pop();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Tenga en cuenta que la función miembro pop() de las colas en C++ (queue, priority_queue, etc.) no retornan el valor extraído. Esto es así para evitar crear copias de los objetos dentro de la cola. De este modo la función top() devuelve una referencia al elemento mismo que se encuentra en la cola, y pop() lo remueve sin devolver nada. Así nos evitamos de crear copias temporales de la instancia removida.&lt;br /&gt;&lt;br /&gt;Para poder usar la priority_queue sobre un tipo de dato propio (como Pasajero), debemos ofrecer una implementación del operator&amp;lt;() para comparar distintas instancias de nuestro tipo de dato (este operador se utiliza para saber qué elemento debe salir último de la cola, es decir, el menor elemento tiene menor prioridad):&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;enum Prioridad { Capitan, Hombre, Mujer, Ninio };&lt;br /&gt;&lt;br /&gt;class Pasajero {&lt;br /&gt;public:&lt;br /&gt;  Pasajero(Prioridad p) : prioridad_(p) { }&lt;br /&gt;&lt;br /&gt;  bool operator&amp;lt;(const Pasajero&amp;amp; otro) const {&lt;br /&gt;    return prioridad_ &amp;lt; otro.prioridad_;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  Prioridad prioridad() const { return prioridad_; }&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;  Prioridad prioridad_;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;De este modo, el capitán tiene prioridad 0 y es tomado en cuenta como el de menor prioridad para abandonar el barco. Los pasajeros que mayor prioridad tienen de abandonar el barco son las mujeres y los niños. En este caso podrían tener igual prioridad, no tendría mucho sentido salvar a todos los niños sin sus respectivas madres.&lt;br /&gt;&lt;br /&gt;Ahora podemos crear un ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  Barco titanic;&lt;br /&gt;  titanic.subirPasajero(Pasajero(Capitan));&lt;br /&gt;  titanic.subirPasajero(Pasajero(Mujer));&lt;br /&gt;  titanic.subirPasajero(Pasajero(Hombre));&lt;br /&gt;  titanic.subirPasajero(Pasajero(Mujer));&lt;br /&gt;  titanic.subirPasajero(Pasajero(Ninio));&lt;br /&gt;  titanic.subirPasajero(Pasajero(Hombre));&lt;br /&gt;  titanic.subirPasajero(Pasajero(Ninio));&lt;br /&gt;  // ...&lt;br /&gt;&lt;br /&gt;  list&amp;lt;Pasajero&amp;gt; pasajeros;&lt;br /&gt;  titanic.abandonarBarco(pasajeros);&lt;br /&gt;  &lt;br /&gt;  for (list&amp;lt;Pasajero&amp;gt;::iterator it = pasajeros.begin(),&lt;br /&gt;         end = pasajeros.end(); it != end; ++it) {&lt;br /&gt;    cout &amp;lt;&amp;lt; it-&amp;gt;prioridad() &amp;lt;&amp;lt; &quot;\n&quot;;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;El anterior ejemplo imprime:&lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;3&lt;br /&gt;3&lt;br /&gt;2&lt;br /&gt;2&lt;br /&gt;1&lt;br /&gt;1&lt;br /&gt;0&lt;br /&gt;&lt;/pre&gt;Lo que significa que, sin importar el orden en el cual agregamos los pasajeros, primero extraemos los niños, luego las mujeres, los hombres, y finalmente el capitán.&lt;br /&gt;&lt;br /&gt;Más información:&lt;br /&gt;&lt;a href=&quot;http://www.cplusplus.com/reference/stl/priority_queue/&quot;&gt;http://www.cplusplus.com/reference/stl/priority_queue/&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Priority_queue&quot;&gt;http://en.wikipedia.org/wiki/Priority_queue&lt;/a&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Ingenieros en Sistemas de Información</title>
   <link href="http://dacap.com.ar/blog/dev/ingenieros-en-sistemas-de-informacion"/>
   <updated>2011-03-06T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/dev/ingenieros-en-sistemas-de-informacion</id>
   <content type="html">&lt;p&gt;La carrera de Ingeniería en Sistemas de Información está llena de casos (&lt;em&gt;brain washers&lt;/em&gt;) donde te dicen una y otra vez que &amp;#8220;el ingeniero no debe programar&amp;#8221;. OK, para poner las cosas claras: El ingeniero en sistemas que no programó nunca, o no piensa programar nunca, ni piensa tocar una línea de código, es en pocas palabras alguien que no sirve absolutamente para nada.&lt;/p&gt;

&lt;p&gt;Puedo enumerar algunos caminos que un Ingeniero en Sistemas de Información quisiera tomar para esquivar la programación: diseñador, arquitecto, investigación, project manager, testing, calidad. Pero igualmente no vale la pena ser exhaustivos, ya que todos tienen la misma respuesta: Si nunca programaste, nunca vas a poder hacer otra cosa bien.&lt;/p&gt;

&lt;p&gt;Por ejemplo, no concibo a la figura de un diseñador que nunca programó. Siendo el diseñador alguien que &amp;#8220;fabrica&amp;#8221; las bases para los programadores, ¿cómo puede entender alguien qué es bueno para los programadores si nunca programó? Lo mismo se aplica a la arquitectura del sistema que van a usar los programadores a lo largo de todo el desarrollo. A un project manager que se encarga de manejar programadores. A los testers que se encargan de probar código de programadores. La calidad que intenta arreglar y optimizar todo el proceso que deben seguir los programadores. En todo esto el punto clave es: Si nunca fui programador ¿puedo comprenderlos y mejorar su desarrollo o su forma de trabajo? La respuesta es no.&lt;/p&gt;

&lt;p&gt;El único fin de la Ingeniería en Sistema de Información es hacer un sistema o mantener un sistema heredado, y la única forma de hacerlo es comunicándose con la computadora programando. Por lo tanto, los programadores son la pieza fundamental. Sin programación, no hay sistema. En consecuencia, deberías comenzar a respetar a los programadores.&lt;/p&gt;

&lt;p&gt;Consejo: Si estás estudiando Ingeniería en Sistemas de Información, aprende a programar. Si no te gusta programar, no importa, el mundo sigue andando con gente que estudió y trabaja de algo que no le gusta, tal vez a costa del sufrimiento de otros.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Intros</title>
   <link href="http://dacap.com.ar/blog/games/intros"/>
   <updated>2010-12-30T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/games/intros</id>
   <content type="html">&lt;div class='post'&gt;
La primera intro (u &quot;opening&quot;) que me sorprendió en mi vida fue la de Tekken para arcade en una pantalla gigante:&lt;br /&gt;&lt;br /&gt;&lt;object width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/kD1q2eY64o0?fs=1&amp;amp;hl=es_ES&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/kD1q2eY64o0?fs=1&amp;amp;hl=es_ES&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;Te ponía la piel de gallina.&lt;br /&gt;&lt;br /&gt;Después la intro de Tekken 2 para PlayStation que era para caerse de la silla, con una breve introducción a cada personaje y una música increíble:&lt;br /&gt;&lt;br /&gt;&lt;object width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/lJDN7JxWO90?fs=1&amp;amp;hl=es_ES&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/lJDN7JxWO90?fs=1&amp;amp;hl=es_ES&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Tekken 3 de Arcade:&lt;br /&gt;&lt;object width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/0mXK5ZqqffA?fs=1&amp;amp;hl=es_ES&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/0mXK5ZqqffA?fs=1&amp;amp;hl=es_ES&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Tekken 3 de PlayStation (nivel cinematográfico, aunque es notorio que los modelos 3D y la animación todavía no estaban tan avanzadas para ese entonces):&lt;br /&gt;&lt;br /&gt;&lt;object width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/7qmU4wQqKQI?fs=1&amp;amp;hl=es_ES&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/7qmU4wQqKQI?fs=1&amp;amp;hl=es_ES&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Igualmente, la intro que más se gravo en mi cabeza es la de Twisted Metal 2. Con menores recursos que las otras (animación 2D, imágenes estáticas que se rotan y desplazan, como una animación de Flash) pero con una voz de fondo espectacular, Welcome to Twisted Metal:&lt;br /&gt;&lt;br /&gt;&lt;object width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/Z2L-2cOIwAc?fs=1&amp;amp;hl=es_ES&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/Z2L-2cOIwAc?fs=1&amp;amp;hl=es_ES&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;También vale la pena ver los &lt;a href=&quot;http://www.youtube.com/watch?v=v0PWFrMZch8&quot;&gt;finales de Twisted Metal 2&lt;/a&gt;, no tienen desperdicio.
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Follow</title>
   <link href="http://dacap.com.ar/blog/ideas/follow"/>
   <updated>2010-12-03T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/follow</id>
   <content type="html">&lt;p&gt;Una importante aclaración sobre el botón &amp;#8220;Follow&amp;#8221; (&lt;em&gt;Seguir&lt;/em&gt;) de Twitter, principalmente para los políticos que lo usan: A veces, este botón no significa algo bueno. Es decir, que un político tenga 100.000 seguidores no significa nada. El &amp;#8220;Follow&amp;#8221; no equivale a un &amp;#8220;Lo voy a seguir&amp;#8221; en repuesta a &amp;#8220;Síganme, no los voy a defraudar&amp;#8221;. El &amp;#8220;Follow&amp;#8221; significa &amp;#8220;¡Síganlo, que no se escape!&amp;#8221;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Sueños</title>
   <link href="http://dacap.com.ar/blog/ideas/suenios"/>
   <updated>2010-11-17T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/suenios</id>
   <content type="html">&lt;p&gt;Nunca te vayas a dormir después de usar la computadora. La computadora roba sueños. Si te preguntas por qué ya no sueñas más, es porque usas la computadora antes de dormir. 30 o 60 minutos antes lee un cacho de novela o libro de filosofía. No funciona si lees libros técnicos.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Simulador Político</title>
   <link href="http://dacap.com.ar/blog/ideas/simulador-politico"/>
   <updated>2010-09-30T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/simulador-politico</id>
   <content type="html">&lt;p&gt;Así como existen simuladores de vuelo para entrenar pilotos, debería existir un simulador para aspirantes a político. La idea sería meterlos dentro de una máquina y hasta que no dejan de destruir naciones, no se los saca al mundo real.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Iostream - Redireccionar clog para "loguear" en un archivo</title>
   <link href="http://dacap.com.ar/blog/cpp/iostream-redireccionar-clog-para-loguear-en-un-archivo"/>
   <updated>2010-09-18T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/iostream-redireccionar-clog-para-loguear-en-un-archivo</id>
   <content type="html">&lt;div class='post'&gt;
La &lt;a href=&quot;http://www.cplusplus.com/reference/iostream/&quot;&gt;iostream&lt;/a&gt; es la librería de entrada y salida de C++. Existen algunos &lt;a href=&quot;http://en.wikipedia.org/wiki/Standard_streams&quot;&gt;streams estándares&lt;/a&gt; de salida: std::cout, std::cerr y std::clog. El primero apunta a la consola, y los dos últimos... también. Las diferencias son estas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;cout apunta a la salida estándar STDOUT (texto de resultado esperado de un programa);&lt;br /&gt;&lt;li&gt;cerr y clog apuntan a STDERR (salida de errores y cualquier otra porquería).&lt;br /&gt;&lt;/ul&gt;Aunque a primera vista todo el texto se envía a la consola, uno puede redireccionar la salida a otros lados. Por ejemplo, imaginemos que tenemos el siguiente programa test.exe:&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  cout &amp;lt;&amp;lt; &quot;A\n&quot;;&lt;br /&gt;  cerr &amp;lt;&amp;lt; &quot;B\n&quot;;&lt;br /&gt;  clog &amp;lt;&amp;lt; &quot;C\n&quot;;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;/pre&gt;Al ejecutarlo, obtenemos por pantalla las tres líneas:&lt;pre class=&quot;console&quot;&gt;test.exe [ENTER]&lt;br /&gt;A&lt;br /&gt;B&lt;br /&gt;C&lt;br /&gt;&lt;/pre&gt;Pero resulta interesante saber que podemos redireccionar el STDOUT a un archivo y el STDERR a otro. Ejemplo:&lt;pre class=&quot;console&quot;&gt;test.exe 1&gt;stdout.txt 2&gt;stderr.txt&lt;/pre&gt;¿Qué demonios es 1 y 2? Los archivos tienen un &lt;a href=&quot;http://en.wikipedia.org/wiki/File_descriptor&quot;&gt;descriptor que los identifica&lt;/a&gt;, 1 es para la STDOUT, y 2 para STDERR. El signo mayor (&amp;gt;) significa que &quot;quiero redireccionar toda la salida de texto que vaya para este descriptor a este archivo&quot;. En el anterior ejemplo logramos obtener dos archivos distintos, stdout.txt que contiene una línea (A), y stderr.txt que contiene dos líneas (B y C).&lt;p&gt;Generalmente, los &lt;a href=&quot;http://en.wikipedia.org/wiki/Server_log&quot;&gt;logs&lt;/a&gt; van a un archivo, no a la pantalla. Aunque por defecto clog mande todo a STDERR, resulta útil redireccionar este stream a un archivo propio (por ejemplo, test.log). De esta forma, podemos hacer uso de clog para &quot;loguear&quot; todo lo que nuestro programa hace.&lt;p&gt;&lt;b&gt;¿Cómo se redirecciona clog?&lt;/b&gt; Básicamente los streams de C++ tienen un &lt;a href=&quot;http://www.cplusplus.com/reference/iostream/streambuf/&quot;&gt;streambuf&lt;/a&gt; asociado, y éste es el realmente encargado de leer y escribir datos (en la pantalla, en un archivo, en un string en memoria, etc.). Por lo tanto, si creamos un fstream y le colocamos su propio streambuf a clog, podemos usar clog como un &quot;alias&quot; del fstream original (clog va a estar compartiendo el mismo streambuf que el fstream). El código resultante es bastante sencillo:&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  // Creamos un archivo de salida para logging.&lt;br /&gt;  ofstream test_log;&lt;br /&gt;  test_log.open(&quot;test.log&quot;);&lt;br /&gt;&lt;br /&gt;  // Obtenemos el streambuf actual de clog (esto&lt;br /&gt;  // lo usaremos luego para restaurar el streambuf&lt;br /&gt;  // a su valor original, por si las moscas).&lt;br /&gt;  streambuf* old_rdbuf = clog.rdbuf();&lt;br /&gt;&lt;br /&gt;  // Reemplazamos el streambuf de clog con el del archivo.&lt;br /&gt;  // Ahora ambos streams utilizarán el mismo streambuf (es&lt;br /&gt;  // decir, escriben en el archivo test.log).&lt;br /&gt;  clog.rdbuf(test_log.rdbuf());&lt;br /&gt;&lt;br /&gt;  // Hacemos lo mismo que el ejemplo original.&lt;br /&gt;  cout &amp;lt;&amp;lt; &quot;A\n&quot;;&lt;br /&gt;  cerr &amp;lt;&amp;lt; &quot;B\n&quot;;&lt;br /&gt;  clog &amp;lt;&amp;lt; &quot;C\n&quot;;&lt;br /&gt;  &lt;br /&gt;  // Restauramos el viejo streambuf de clog.&lt;br /&gt;  clog.rdbuf(old_rdbuf);&lt;br /&gt;&lt;br /&gt;  // Cerramos el archivo.&lt;br /&gt;  test_log.close();&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;/pre&gt;Y listo, ahora podemos hacer lo mismo que antes:&lt;pre class=&quot;console&quot;&gt;test.exe 1&gt;stdout.txt 2&gt;stderr.txt&lt;/pre&gt;Con lo cual obtenemos tres archivos:&lt;ul&gt;&lt;li&gt;stdout.txt con la línea A.&lt;br /&gt;&lt;li&gt;stderr.txt con la línea B.&lt;br /&gt;&lt;li&gt;test.log con la línea C.&lt;br /&gt;&lt;/ul&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Compartidor</title>
   <link href="http://dacap.com.ar/blog/ideas/compartidor"/>
   <updated>2010-09-15T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/compartidor</id>
   <content type="html">&lt;p&gt;Detrás del éxito de las redes sociales como Facebook o Twitter, se esconde uno de los sentimientos más primitivos del ser humano: El compartir algo que nos gusta. Lamentablemente, en vez de contemplar y aprovechar al máximo nuestras propias vivencias y emociones, intentamos rellenar el alma de las demás personas. Así podemos identificar a un nuevo ser que emerge de la Internet con total majestuosidad: el compartidor.&lt;/p&gt;

&lt;p&gt;El compartidor no es sólo el tipo que comparte, es el tipo que en su interior, muy en lo profundo de su ser, cree que todo lo que ve, escucha, huele y siente, puede ser transmitido a otros. Potenciado a base de redes sociales, el sentimiento crece en un éxtasis total al ser compartido lo antes posible con todos los amigos. Con la telefonía móvil a su favor, destruye sus sentimientos al mismo tiempo que teclea su próximo mensaje a compartir.&lt;/p&gt;

&lt;p&gt;Claro que, como siempre me gusta darle un giro inesperado a las cosas, no puedo despedirme sin compartir:&lt;/p&gt;
&lt;object height='385' width='480'&gt;&lt;param name='movie' value='http://www.youtube.com/v/t4W367qUohA?fs=1&amp;amp;hl=es_ES' /&gt;&lt;param name='allowFullScreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;embed allowfullscreen='true' allowscriptaccess='always' height='385' src='http://www.youtube.com/v/t4W367qUohA?fs=1&amp;amp;hl=es_ES' type='application/x-shockwave-flash' width='480' /&gt;&lt;/object&gt;</content>
 </entry>
 
 <entry>
   <title>Fuerza de gravedad</title>
   <link href="http://dacap.com.ar/blog/dev/fuerza-de-gravedad"/>
   <updated>2010-09-07T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/dev/fuerza-de-gravedad</id>
   <content type="html">&lt;p&gt;El desarrollo de páginas web, y la evolución del universo de la Internet, tuvo una gran fuerza en su contra que hizo, entre otras cosas, que una cantidad inimaginable de personas alrededor del mundo no puedan plasmar sus ideas y creatividad sobre uno de los soportes más ricos conocidos hoy en día: el hipertexto y la multimedia (dos palabras prehistóricas). Dicha fuerza se la conoce como Internet Explorer.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Miembros virtuales</title>
   <link href="http://dacap.com.ar/blog/cpp/miembros-virtuales"/>
   <updated>2010-08-30T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/miembros-virtuales</id>
   <content type="html">&lt;div class='post'&gt;
Una &lt;a href=&quot;http://en.wikipedia.org/wiki/Virtual_function&quot;&gt;función miembro virtual&lt;/a&gt; tiene la característica de poder ser sobrecargada por subclases para agregar un comportamiento propio. Pero existen dos lugares en donde las funciones virtuales toman un comportamiento especial: en los constructores y los destructores.&lt;br /&gt;&lt;br /&gt;Veamos el siguiente ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Lugar {&lt;br /&gt;public:&lt;br /&gt;  Lugar() {                     // El lugar es creado&lt;br /&gt;    creacion();                 // Llamamos a la función virtual&lt;br /&gt;  }&lt;br /&gt;  virtual ~Lugar() {            // El lugar es destruido&lt;br /&gt;    destruccion();              // Llamamos a la función virtual&lt;br /&gt;  }&lt;br /&gt;protected:&lt;br /&gt;  virtual void creacion()    { }&lt;br /&gt;  virtual void destruccion() { }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Universo : public Lugar {&lt;br /&gt;protected:&lt;br /&gt;  void creacion()    { cout &amp;lt;&amp;lt; &quot;Big Bang\n&quot;; }&lt;br /&gt;  void destruccion() { cout &amp;lt;&amp;lt; &quot;Big Crunch\n&quot;; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  Universo i_am_god;  // ¿Qué imprime este programa?&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;La idea de todo método virtual es poder proporcionar puntos de extensión a las clases derivadas. En este caso, ¿&lt;i&gt;Lugar::creacion&lt;/i&gt; funciona como punto de extensión para clases derivadas? La respuesta es: no. El anterior programa no imprime nada.&lt;/p&gt;&lt;p&gt;Aunque creamos una instancia de &lt;i&gt;Universo&lt;/i&gt;, ni el método &lt;i&gt;Universo::creacion&lt;/i&gt; ni &lt;i&gt;Universo::destruccion&lt;/i&gt; se llamaron. ¿A qué se debe esto? Imaginemos que al crear un &lt;i&gt;Universo&lt;/i&gt;, primero debemos crear un &lt;i&gt;Lugar&lt;/i&gt; en su totalidad, para luego comenzar a crear el universo. Es por eso que si llamamos a &lt;i&gt;creacion&lt;/i&gt; mientras estamos construyendo el &lt;i&gt;Lugar&lt;/i&gt;, no podemos alcanzar el método &lt;i&gt;Universo::creacion&lt;/i&gt; ya que el &lt;i&gt;Universo&lt;/i&gt; todavía no comenzó a ser construido (no tiene un &lt;i&gt;Lugar&lt;/i&gt; completamente construido donde existir).&lt;/p&gt;&lt;p&gt;La secuencia correcta es:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Alojamos un cacho de memoria suficiente como para que entre el universo.&lt;br /&gt;Algo así como hacer un: &lt;i&gt;this = malloc(sizeof(Universo))&lt;/i&gt; en C.&lt;br /&gt;&lt;li&gt;Construimos el &lt;i&gt;Lugar&lt;/i&gt; usando la memoria recién obtenida como puntero &lt;i&gt;this&lt;/i&gt;.&lt;br /&gt;&lt;li&gt;Luego construimos el &lt;i&gt;Universo&lt;/i&gt;.&lt;br /&gt;&lt;li&gt;Y recién ahí somos capaces de llamar a &lt;i&gt;Universo::creacion&lt;/i&gt; y asegurarnos que estaremos usando el método especializado de la subclase.&lt;br /&gt;&lt;/ol&gt;&lt;p&gt;&lt;b&gt;¿Puedo llamar a &lt;i&gt;creacion&lt;/i&gt; dentro del constructor de &lt;i&gt;Universo&lt;/i&gt;?&lt;/b&gt; La respuesta es sí, todo es posible. ¿Es correcto? Mmmhh, depende, si alguien hace una subclase de &lt;i&gt;Universo&lt;/i&gt; y sobreescribe &lt;i&gt;creacion&lt;/i&gt;, nuevamente estará en el mismo problema que estamos mostrando aquí.&lt;/p&gt;&lt;p&gt;&lt;b&gt;¿Por qué en el destructor de &lt;i&gt;Lugar&lt;/i&gt; no llama a &lt;i&gt;Universo::destruccion&lt;/i&gt;?&lt;/b&gt; Porque el &lt;i&gt;Universo&lt;/i&gt; ya está destruido (¿cruncheado?) para cuando llegamos al destructor del &lt;i&gt;Lugar&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;&lt;b&gt;¿Cómo lo soluciono?&lt;/b&gt; Usar puntos de extensión en los constructores y destructores presentan más problemas que ventajas. La solución es no usarlos. Solución (obvia):&lt;/p&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Lugar {&lt;br /&gt;public:&lt;br /&gt;  Lugar() { }&lt;br /&gt;  virtual ~Lugar() { }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Universo : public Lugar {&lt;br /&gt;public:&lt;br /&gt;  Universo()  { cout &amp;lt;&amp;lt; &quot;Big Bang\n&quot;; }&lt;br /&gt;  ~Universo() { cout &amp;lt;&amp;lt; &quot;Big Crunch\n&quot;; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  Universo i_am_god;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;En un próximo post voy a dar un ejemplo más complejo donde esto no sirve.&lt;/p&gt;&lt;p&gt;&lt;b&gt;¿Y qué sucede si llamo una función miembro abstracta en el constructor o destructor?&lt;/b&gt; Es el desastre total. Completamente ilegal. Imposible. Una violación absoluta a la razón y el sentido común. Imagine este código:&lt;/p&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Lugar {&lt;br /&gt;public:&lt;br /&gt;  Lugar() { creacion(); }        // Ja llamo a creacion()&lt;br /&gt;protected:&lt;br /&gt;  virtual void creacion() = 0;   // Jaja y no lo defino ;)&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Universo : public Lugar {&lt;br /&gt;protected:&lt;br /&gt;  void creacion() { }            // Jajaja sólo puede llamarme a mí!&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  Universo i_am_god_x2;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;Al compilar este código con gcc obtenemos un warning porque estamos llamando un método abstractor en el constructor, y un error de enlace al crear el ejecutable ya que &lt;i&gt;Lugar::creacion&lt;/i&gt; no está definido:&lt;/p&gt;&lt;pre class=&quot;console&quot;&gt;test.cpp: In constructor 'Lugar::Lugar()':&lt;br /&gt;test.cpp:7:22: warning: abstract virtual 'virtual void Lugar::creacion()' called from constructor&lt;br /&gt;C:\temp\ccstr9Hr.o:test.cpp:(.text$_ZN5LugarC2Ev[Lugar::Lugar()]+0x16): undefined reference to `Lugar::creacion()'&lt;br /&gt;collect2: ld returned 1 exit status&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Aunque dijimos explícitamente que Lugar::creacion() es abstracto (=0), eso no significa que no debamos definirlo en este caso tan particular.&lt;/p&gt;&lt;p&gt;Referencias:&lt;br&gt;Sutter, Herb &amp; Alexandrescu, Andrei (2004). Item 49: Avoid calling virtual functions in constructors and destructors. &lt;em&gt;C++ Coding Standards: 101 Rules, Guidelines, and Best Practices.&lt;/em&gt; Boston, MA: Addison-Wesley Professional, (ISBN 0321113586).
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Ridículo</title>
   <link href="http://dacap.com.ar/blog/dev/ridiculo"/>
   <updated>2010-08-22T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/dev/ridiculo</id>
   <content type="html">&lt;p&gt;A veces la gente pide cosas completamente imposibles. &lt;a href='http://code.google.com/p/chromium/issues/detail?id=51583'&gt;Esta issue&lt;/a&gt; de Chromium me hizo reír. El tipo tenía problemas descargando archivos con su versión de Chrome, reporta la issue, pero al mismo tiempo dice: &amp;#8220;But please don&amp;#8217;t ask me to change another version&amp;#8221;&amp;#8230;&lt;/p&gt;

&lt;p&gt;O sea ¿Tenes un problema con el software que usas pero no querés ni hacer el mínimo esfuerzo de actualizarlo? ¿¡Inclusive si eso significa hacer un simple doble-click?!&lt;/p&gt;

&lt;p&gt;Las respuestas a la issue son geniales.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>TODO (a hacer)</title>
   <link href="http://dacap.com.ar/blog/ideas/todo-a-hacer"/>
   <updated>2010-08-05T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/todo-a-hacer</id>
   <content type="html">&lt;p&gt;Supongo que todos (los geeks) suelen tener un txt con una lista de &amp;#8220;cosas a hacer&amp;#8221; (un &amp;#8220;to do&amp;#8221;). Hoy me di cuenta que, con justa razón, tengo las tareas &amp;#8220;a hacer&amp;#8221; a un paso de la papelera.&lt;/p&gt;
&lt;div class='separator' style='clear: both; text-align: center;'&gt;
&lt;img border='0' src='DoNotDo.png' /&gt;
&lt;/div&gt;
&lt;p&gt;¿Será que nunca termino de hacer todo lo que me gustaría hacer?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Botones</title>
   <link href="http://dacap.com.ar/blog/dev/botones"/>
   <updated>2010-08-03T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/dev/botones</id>
   <content type="html">&lt;p&gt;Veamos los siguientes requerimientos. Tenemos tres clases de botones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/Button_%28computing%29'&gt;Button&lt;/a&gt;: El botón común que al presionarlo ejecuta un comando (OK, Cancel, Yes, No, Close, Kill Process, etc.)&lt;/li&gt;

&lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/Check_box'&gt;Check-box&lt;/a&gt;: Una caja para poner un tilde.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/Radio_button'&gt;Radio-button&lt;/a&gt;: Un conjunto de botones redondos para seleccionar una opción entre varias.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cada clase de botón puede verse y actuar como otra clase al mismo tiempo. Por ejemplo: un check-box puede verse como un button pero actuar como check-box, o tres buttons pueden actuar como radio-buttons pero verse como buttons.&lt;/p&gt;

&lt;p&gt;Además, existen algunas propiedades específicas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Los botones que se ven como buttons pueden tener cuatro valores que indican la redondez de cada una de las cuatro esquinas. Recuerde que un check-box o un radio-button puede lucir como un button.&lt;/li&gt;

&lt;li&gt;El comportamiento de los radio-buttons necesita de un grupo que los reuna (por ejemplo, un ID que indica que varios radio-buttons pertenecen al mismo grupo). Recuerde que un button o un check-box puede actuar como un radio-button.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class='separator' style='clear: both; text-align: center;'&gt;
&lt;img border='0' src='Buttons.png' /&gt;
&lt;/div&gt;
&lt;p&gt;¿Cómo resolvería este problema con objetos? Esto es un excelente candidato para aplicar &lt;a href='http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller'&gt;MVC&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Chistes</title>
   <link href="http://dacap.com.ar/blog/ideas/chistes"/>
   <updated>2010-07-31T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/chistes</id>
   <content type="html">&lt;p&gt;Los eventos de la vida no son aleatorios. Son una hermosa y perfecta sucesión de chistes que se van desencadenando a medida que crecemos.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Blogs</title>
   <link href="http://dacap.com.ar/blog/ideas/blogs"/>
   <updated>2010-07-31T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/blogs</id>
   <content type="html">&lt;p&gt;En el futuro, los diarios, las páginas web, los blogs, los microblogs, SMS y todo medio de comunicación escrito, será reemplazado por una alternativa más económica y efectiva: El yoctoblogging. Todo podrá ser dicho con monosílabos: soy, yo, fui, bien, sí, pis, más, mal, gas, ¿vos?, ¿y?&amp;#8230;&lt;/p&gt;

&lt;p&gt;El tiempo libre será tan poco que sólo tendremos lo suficiente como para escribir (y leer) este tipo de mensajes.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Tentación</title>
   <link href="http://dacap.com.ar/blog/ideas/tentacion"/>
   <updated>2010-07-27T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/tentacion</id>
   <content type="html">&lt;div class='separator' style='clear:both;text-align:center;'&gt;
&lt;img border='0' src='GoogleChrome.png' /&gt;
&lt;/div&gt;
&lt;p&gt;A veces siento que me mira y me habla&amp;#8230; y escucho &lt;em&gt;&amp;#8220;vení, haceme click, dale ;) &amp;#8230; tengo un montón de cosas para ofrecerte&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Al final, siempre me defrauda.&lt;/p&gt;
&lt;div style='clear:both;'&gt;
&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Apuntes y creatividad</title>
   <link href="http://dacap.com.ar/blog/ideas/apuntes-y-creatividad"/>
   <updated>2010-07-27T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/apuntes-y-creatividad</id>
   <content type="html">&lt;p&gt;Consejo: Si vas a enseñar una materia en la facultad o un curso, ¿por qué no agregarle un poco de creatividad al asunto? En vez de usar los mismos ejemplos del libro de referencia, a veces es bueno inventar otros (inclusive, evitar usar una escaneada del libro puede ser una buena idea).&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Interfaces gráficas interesantes para diseñar</title>
   <link href="http://dacap.com.ar/blog/dev/interfaces-graficas-interesantes-para-diseniar"/>
   <updated>2010-07-26T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/dev/interfaces-graficas-interesantes-para-diseniar</id>
   <content type="html">&lt;p&gt;Esta es una lista de interfaces gráficas interesantes para resolver:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Una interfaz gráfica que pueda ser usada inmediatamente por cualquiera que nunca haya visto una computadora.&lt;/li&gt;

&lt;li&gt;Un lenguaje de scripting que me permita hacer &lt;em&gt;cualquier cosa&lt;/em&gt; en el sistema operativo, sin necesidad de escribir una línea de código. Por ejemplo, una interfaz para configurar una red de pipes y filtros, donde por las tuberías puede pasar cualquier tipo de dato (texto, datos binarios crudos, imágenes, audio, logs, planillas de excel, bases de dato, páginas web, mails, código fuente, etc.) y los filtros los pueden transformar en cualquier cosa.&lt;/li&gt;

&lt;li&gt;Una interfaz que permita hacer control de versiones con Git con varios repositorios remotos de forma totalmente gráfica, sólo con el mouse. Comandos complejos como rebase podrían ser un simple drag and drop. Debería poder tener una visión de cada repositorio como una pequeña computadora a la que le puedo hacer pull y push (por branch). Etc.&lt;/li&gt;

&lt;li&gt;Un editor de texto como Microsoft Word o OpenOffice.org Writer que produzca documentos de tan buena calidad como LaTeX.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sólo ideas. ¿Para proyectos open source? ¿para proyectos comerciales?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Alcance</title>
   <link href="http://dacap.com.ar/blog/scifi/alcance"/>
   <updated>2010-07-26T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/scifi/alcance</id>
   <content type="html">&lt;p&gt;Estaba comiendo en un bar. Levanto la vista y miro el televisor. Un tipo pidiendo limosna a un periodista. El periodista lo mira y le dice: &amp;#8220;Señor, yo estoy para mostrarle al mundo sus miserias&amp;#8221;. El tipo pega la vuelta y sigue comiendo basura. Yo sigo comiendo. Un pibe se acerca y me pide limosna. Lo miro, le doy una moneda, y pienso: &amp;#8220;Que poco puedo cambiar este mundo&amp;#8221;. Sigo comiendo.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Cuentos</title>
   <link href="http://dacap.com.ar/blog/scifi/cuentos"/>
   <updated>2010-07-25T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/scifi/cuentos</id>
   <content type="html">&lt;p&gt;Un día un tipo se levantó de la cama y se puso a escribir un cuento. Para la noche ya lo había terminado. El cuento era tan bueno que no podía creerlo. Lo leyó una y otra vez, era increíble.&lt;/p&gt;

&lt;p&gt;Nunca más vieron al tipo.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Con el cerebro</title>
   <link href="http://dacap.com.ar/blog/ideas/con-el-cerebro"/>
   <updated>2010-07-25T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/ideas/con-el-cerebro</id>
   <content type="html">&lt;p&gt;Llegará el día que programaremos con el cerebro. Los atajos de teclado no servirán de nada. Simplemente miro una ubicación, pienso en qué quiero escribir y&amp;#8230; BAM! ahí van apareciendo las letras por arte de magia.&lt;/p&gt;

&lt;p&gt;Eso es un editor de texto.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Descargar MinGW con gcc 4.5 automáticamente</title>
   <link href="http://dacap.com.ar/blog/cpp/descargar-mingw-con-gcc-4-5-automaticamente"/>
   <updated>2010-06-06T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/descargar-mingw-con-gcc-4-5-automaticamente</id>
   <content type="html">&lt;p&gt;Este post se podría llamar:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;¿Cómo instalar MinGW? &lt;br /&gt; ¿Cómo instalar y usar gcc 4.5 en Windows? &lt;br /&gt; ¿Cómo compilar programas de C o C++ en Windows? &lt;br /&gt; O también, ¿puedo portar MinGW en un pendrive?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cualquiera de los casos se responde con el siguiente archivo: &lt;a href='http://dacap.com.ar/files/MinGW-Downloader.zip'&gt;MinGW-Downloader.zip&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Los pasos a seguir son los siguientes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cree una carpeta donde descomprimir &lt;code&gt;MinGW-Downloader.zip&lt;/code&gt; (por ejemplo, &lt;code&gt;C:\Compilers&lt;/code&gt;, o &lt;code&gt;C:\GNU&lt;/code&gt;, lo importante es que la carpeta no contenga espacios!)&lt;/li&gt;

&lt;li&gt;Descomprima &lt;code&gt;MinGW-Downloader.zip&lt;/code&gt; en esa carpeta&lt;/li&gt;

&lt;li&gt;Ejecute el archivo &lt;code&gt;C:\Compilers\MinGW-Downloader\MinGW-4.5-Downloader.bat&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;Espere&amp;#8230;&lt;/li&gt;

&lt;li&gt;Una vez finalizado deberá ver algunos mensajes en la pantalla diciéndole si tuvo éxito (SUCCESS), inclusive el script intenta compilar un programa en C y otro en C++.&lt;/li&gt;

&lt;li&gt;Listo, ya tiene MinGW con gcc 4.5 disponible en su máquina.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Puede usar el script &lt;code&gt;Run-cmd-with-MinGW-4.5.bat&lt;/code&gt; para ejecutar la línea de comandos de Windows y tener el compilador disponible (gcc, g++, etc.) en la variable PATH. Lo importante es que el proceso de descarga no modifica ninguna variable de entorno suya (PATH), por lo tanto, podría borrar la carpeta &lt;code&gt;C:\Compilers&lt;/code&gt; y empezar desde cero siempre que así lo desee.&lt;/p&gt;

&lt;p&gt;Puede mover la carpeta &lt;code&gt;C:\Compilers\MinGW-Downloader\MinGW-4.5&lt;/code&gt; a &lt;code&gt;C:\MinGW-4.5&lt;/code&gt; y borrar &lt;code&gt;C:\Compilers\MinGW-Downloader&lt;/code&gt; completamente. Si quiere tener el compilador disponible desde cualquier aplicación (por ejemplo, desde un editor de texto o IDE), podría agregar la ruta &lt;code&gt;C:\MinGW-4.5\bin&lt;/code&gt; a su PATH.&lt;/p&gt;

&lt;p&gt;Cabe destacar que la carpeta &lt;code&gt;MinGW-4.5&lt;/code&gt; (&lt;code&gt;C:\Compilers\MinGW-Downloader\MinGW-4.5&lt;/code&gt;) y el archivo &lt;code&gt;Run-cmd-with-MinGW-4.5.bat&lt;/code&gt; los puede mover donde usted desee (por ejemplo, llevarlos en un pen drive), sólo tenga en cuenta que para hacer esto los dos tienen que estar en el mismo directorio (e.j. &lt;code&gt;C:\MinGW-4.5&lt;/code&gt; y &lt;code&gt;C:\Run-cmd-with-MinGW-4.5.bat&lt;/code&gt;).&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Shared Pointers de C++0x</title>
   <link href="http://dacap.com.ar/blog/cpp/shared-pointers-de-cpp0x"/>
   <updated>2010-05-29T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/shared-pointers-de-cpp0x</id>
   <content type="html">&lt;div class='post'&gt;
En C usted puede hacer esto:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;&lt;br /&gt;struct Persona { };&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  Persona* a = malloc(sizeof(Persona));&lt;br /&gt;  free(a);&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Un ejemplo equivalente en C++:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;class Persona { };&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  Persona* a = new Persona();&lt;br /&gt;  delete a;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Por cada &lt;b&gt;malloc&lt;/b&gt; existe un &lt;b&gt;free&lt;/b&gt; (al menos que use reallocs), y por cada &lt;b&gt;new&lt;/b&gt; existe un &lt;b&gt;delete&lt;/b&gt; (y por cada new[] un delete[]).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;¿Existe una forma por la cual C++ se &quot;entere&quot; que ya no quiero usar un puntero?&lt;/b&gt; La respuesta es: No, no existe. C++ no tiene un &lt;a href=&quot;http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)&quot;&gt;garbage collector&lt;/a&gt;. Pero existen &lt;a href=&quot;http://cmasomenos.blogspot.com/2009/11/punteros-por-ambito-scoped-pointers.html&quot;&gt;clases que pueden ayudarnos&lt;/a&gt;, como el viejo y tan poco querido &lt;a href=&quot;http://cmasomenos.blogspot.com/2008/06/excepciones-raii-y-autoptr.html&quot;&gt;auto_ptr&lt;/a&gt;, o los mejorados &lt;a href=&quot;http://www.google.com/search?q=unique_ptr+Class&amp;btnI=1&quot;&gt;unique_ptr&lt;/a&gt;, &lt;a href=&quot;http://www.google.com/search?q=shared_ptr+Class&amp;btnI=1&quot;&gt;shared_ptr&lt;/a&gt; y &lt;a href=&quot;http://www.google.com/search?q=weak_ptr+Class&amp;btnI=1&quot;&gt;weak_ptr&lt;/a&gt; del nuevo estándar de C++0x (o el &lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B_Technical_Report_1#Smart_pointers&quot;&gt;TR1&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Un &lt;em&gt;shared pointer&lt;/em&gt; es una clase que se encarga de guardar un puntero a un objeto (o tipo de dato), y cuenta la cantidad de referencias que se están haciendo a dicho objeto (es decir, la cantidad de shared pointers que apuntan al mismo objeto). El último shared pointer que se destruya (cuando las referencias llegan a cero), será el encargado de borrar el objeto apuntado (mediante un simple delete).&lt;br /&gt;&lt;br /&gt;Un ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;memory&amp;gt;  // Aquí debería estar shared_ptr&amp;lt;&amp;gt; (GCC 4.4)&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Persona {&lt;br /&gt;  int n;&lt;br /&gt;&lt;br /&gt;public:&lt;br /&gt;  Persona(int n) : n(n) {&lt;br /&gt;    cout &amp;lt;&amp;lt; &quot;Nace la persona &quot; &amp;lt;&amp;lt; n &amp;lt;&amp;lt; &quot;\n&quot;;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  ~Persona() { &lt;br /&gt;    cout &amp;lt;&amp;lt; &quot;Muere la persona &quot; &amp;lt;&amp;lt; n &amp;lt;&amp;lt; &quot;\n&quot;;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  static shared_ptr&amp;lt;Persona&amp;gt; Crear(int n) { &lt;br /&gt;    return shared_ptr&amp;lt;Persona&amp;gt;(new Persona(n));&lt;br /&gt;  }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  shared_ptr&amp;lt;Persona&amp;gt; a(new Persona(1));&lt;br /&gt;  shared_ptr&amp;lt;Persona&amp;gt; b = Persona::Crear(2);&lt;br /&gt;  shared_ptr&amp;lt;Persona&amp;gt; c;&lt;br /&gt;&lt;br /&gt;  cout &amp;lt;&amp;lt; &quot;--- Aquí ambas personas existen ---\n&quot;;&lt;br /&gt;&lt;br /&gt;  c = a; // Aquí c apunta a la persona 1&lt;br /&gt;  b = c; // Ahora b apuntará a la persona 1 (la persona 2 muere porque&lt;br /&gt;         // ya no existen referencias a ella)&lt;br /&gt;&lt;br /&gt;  cout &amp;lt;&amp;lt; &quot;--- Aquí la persona 2 ya no existe ---\n&quot;;&lt;br /&gt;  &lt;br /&gt;  return 0;&lt;br /&gt;}        // Aquí muere la persona 1 (a, b, c apuntaban a ella)&lt;br /&gt;&lt;/pre&gt;La salida del anterior programa es esta:&lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;Nace la persona 1&lt;br /&gt;Nace la persona 2&lt;br /&gt;--- Aquí ambas personas existen ---&lt;br /&gt;Muere la persona 2&lt;br /&gt;--- Aquí la persona 2 ya no existe ---&lt;br /&gt;Muere la persona 1&lt;br /&gt;&lt;/pre&gt;Como puede ver, en el anterior programa se llama sólo dos veces a &quot;new Persona&quot; y dos veces al destructor ~Persona. No debemos preocuparnos por usar &quot;delete&quot;, el shared_ptr&amp;lt;&amp;gt; hace todo por nosotros.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;¿Cómo hago para que la clase shared_ptr funcione en VS2008 SP1 Express?&lt;/b&gt; Debe definir _HAS_TR1 antes de incluir el archivo &amp;lt;memory&amp;gt;. Ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#ifdef _MSC_VER      // Si estamos usando el compilador de Microsoft&lt;br /&gt;  #define _HAS_TR1 1 // Esto hará que se incluyan las clases del TR1 (std::tr1)&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;memory&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;#ifdef _MSC_VER&lt;br /&gt;  using namespace std::tr1; // para tener shared_ptr&amp;lt;&amp;gt; disponible&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;// Resto del ejemplo...&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>C++0x Final Committee Draft (FCD)</title>
   <link href="http://dacap.com.ar/blog/cpp/cpp0x-final-committee-draft-fcd"/>
   <updated>2010-03-31T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/cpp0x-final-committee-draft-fcd</id>
   <content type="html">&lt;div class='post'&gt;
Ya está disponible el documento N3092, &lt;em&gt;Programming Languages — C++, Final Committee Draft&lt;/em&gt;. Este documento es el que más podría corresponder al nuevo estándar ISO de C++ (lo que viene de acá a uno o dos años pueden ser correcciones menores):&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf&quot;&gt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Más información &lt;a href=&quot;http://herbsutter.com/2010/03/13/trip-report-march-2010-iso-c-standards-meeting/&quot;&gt;acá&lt;/a&gt;.
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Improving your applications by statistics</title>
   <link href="http://dacap.com.ar/blog/dev/improving-your-applications-by-statistics"/>
   <updated>2010-03-03T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/dev/improving-your-applications-by-statistics</id>
   <content type="html">&lt;p&gt;If you developed an application and published it in a website, you can use things like google-analytics data to adjust your application. E.g. If everybody is accessing your website with 32-bits, 24-bits and 16-bits screen resolutions, you can discard all considerations about 8-bits modes in your application.&lt;/p&gt;

&lt;p&gt;Things you should add to your application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A way to get usage data from your users. E.g. where they do click, how they call commands (menus, keyboard, toolbars, ribbons, etc.). In this way you could focus improvement in the more common methods to run commands.&lt;/li&gt;

&lt;li&gt;A way to count how many times a command was used. Maybe there are commands that are rarely used, these commands could be more deeper in menus hierarchies and without keyboard shortcut.&lt;/li&gt;

&lt;li&gt;A way to known systems where your application is running. E.g. operating system, version, screen resolution, etc. Improve usability in the most used platform.&lt;/li&gt;

&lt;li&gt;A way to known how many computers are running a specific version of your application. If a version is not used anymore, you can stop supporting it (E.g. Adding patches for a version that nobody uses).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this must be done carefully, with proper check-boxes like &amp;#8220;Do you want to send anonymous data about your usage to improve customer experience?&amp;#8221; in installers, splash screens, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.eclipse.org/epp/usagedata/'&gt;There are some frameworks&lt;/a&gt; to do this kind of work. Anyway you basically need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An HTTP server to accept packages from users (e.g. through POST requests). Each request should be processed by a script (in PHP, ASP, etc.) which should convert the received package into database model.&lt;/li&gt;

&lt;li&gt;A way to differentiate users (you could SHA1 some string like &amp;#8220;local user name + pc host name + app name version&amp;#8221;). Here I don&amp;#8217;t know if the IP could be a good way idea (NAT problems, etc.).&lt;/li&gt;

&lt;li&gt;A way to make HTTP requests from your application (firewall + proxy problems) of all collected usage data of the user (identified by the SHA1).&lt;/li&gt;

&lt;li&gt;A mini-program to process all the database and print some useful reports.&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Emacs: How to open the current buffer with associated application?</title>
   <link href="http://dacap.com.ar/blog/emacs/emacs-how-to-open-the-current-buffer-with-associated-application"/>
   <updated>2010-03-02T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/emacs/emacs-how-to-open-the-current-buffer-with-associated-application</id>
   <content type="html">&lt;p&gt;The following function tries to run the application associated with the current buffer file type (e.g. if you use this function in an .html file, the file will be opened with your default web browser):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defun open-current-file-with-associated-app ()
  (interactive)
  (shell-command (concat &amp;quot;cmd /c \&amp;quot;start &amp;quot; (buffer-file-name) &amp;quot;\&amp;quot;&amp;quot;)))&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>Emacs: How to locate the current buffer in Windows Explorer?</title>
   <link href="http://dacap.com.ar/blog/emacs/emacs-how-to-locate-the-current-buffer-in-windows-explorer"/>
   <updated>2010-03-02T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/emacs/emacs-how-to-locate-the-current-buffer-in-windows-explorer</id>
   <content type="html">&lt;p&gt;You can use the following function to open the Windows Explorer in the directory of the current buffer:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defun locate-current-file-in-explorer ()
  (interactive)
  (cond
   ;; In buffers with file name
   ((buffer-file-name)
    (shell-command (concat &amp;quot;start explorer /e,/select,\&amp;quot;&amp;quot; (replace-regexp-in-string &amp;quot;/&amp;quot; &amp;quot;\\\\&amp;quot; (buffer-file-name)) &amp;quot;\&amp;quot;&amp;quot;)))
   ;; In dired mode
   ((eq major-mode &amp;#39;dired-mode)
    (shell-command (concat &amp;quot;start explorer /e,\&amp;quot;&amp;quot; (replace-regexp-in-string &amp;quot;/&amp;quot; &amp;quot;\\\\&amp;quot; (dired-current-directory)) &amp;quot;\&amp;quot;&amp;quot;)))
   ;; In eshell mode
   ((eq major-mode &amp;#39;eshell-mode)
    (shell-command (concat &amp;quot;start explorer /e,\&amp;quot;&amp;quot; (replace-regexp-in-string &amp;quot;/&amp;quot; &amp;quot;\\\\&amp;quot; (eshell/pwd)) &amp;quot;\&amp;quot;&amp;quot;)))
   ;; Use default-directory as last resource
   (t
    (shell-command (concat &amp;quot;start explorer /e,\&amp;quot;&amp;quot; (replace-regexp-in-string &amp;quot;/&amp;quot; &amp;quot;\\\\&amp;quot; default-directory) &amp;quot;\&amp;quot;&amp;quot;)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;How it works?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you are visiting a buffer associated to a file (with buffer-file-name), the Windows Explorer is opened to focus the file in its directory.&lt;/li&gt;

&lt;li&gt;If you are in dired mode (browsing a directory inside Emacs with dired-mode), it will open that directory in Windows Explorer.&lt;/li&gt;

&lt;li&gt;If you are in eshell-mode, the current working directory will be opened in Windows Explorer.&lt;/li&gt;

&lt;li&gt;As last chance it will open the Windows Explorer in the default directory (where you start emacs). E.g. This can happen if you use this function in &lt;em&gt;scratch&lt;/em&gt; buffer (which is a buffer without an associated file).&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>STL string, parseando un número de versión</title>
   <link href="http://dacap.com.ar/blog/cpp/stl-string-parseando-un-numero-de-version"/>
   <updated>2010-01-27T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/stl-string-parseando-un-numero-de-version</id>
   <content type="html">&lt;div class='post'&gt;
En esta ocasión vamos a ver cómo usar la clase &lt;em&gt;std::string&lt;/em&gt; para convertir una cadena de caracteres (como &quot;1.2.3&quot;) en una clase &quot;Version&quot; que tenga una interfaz simple de utilizar (por ejemplo, que permita comparar versiones).&lt;br /&gt;&lt;br /&gt;Los pasos son simples:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;tenemos como entrada una cadena de caracteres,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;dividimos la cadena según el caracter '.' (punto),&lt;br /&gt;&lt;/li&gt;&lt;li&gt;convertimos cada parte a entero,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;guardamos cada número entero de forma ordenada en un vector.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;El punto 2 es en el cual nos vamos a enfocar más. &lt;em&gt;El código mostrado aquí es a modo de ejemplo, y está lejos de ser el más óptimo.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Antes de comenzar ¿Podemos usar &lt;a href=&quot;http://www.cplusplus.com/reference/clibrary/cstring/strcmp/&quot;&gt;strcmp&lt;/a&gt; para comparar dos versiones?&lt;/b&gt; No, no podemos. Ejemplo: strcmp(&quot;1.9&quot;, &quot;1.10&quot;) &amp;gt; 0, cuando en realidad la versión 1.9 es menor a 1.10.&lt;br /&gt;&lt;br /&gt;Imaginemos que tenemos una cadena: &lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;std::string ver = &quot;1.10.2.3&quot;;&lt;br /&gt;&lt;/pre&gt;La clase &lt;a href=&quot;http://www.cplusplus.com/reference/string/string/&quot;&gt;std::string&lt;/a&gt; tiene la función miembro &lt;a href=&quot;http://www.cplusplus.com/reference/string/string/find/&quot;&gt;find&lt;/a&gt;, la cual podemos usar para buscar casi cualquier cosa dentro de la cadena. ¿Qué debemos buscar? Los puntos, sabiendo donde está cada punto, podemos ir recortando la cadena en sus distintas partes (&quot;1&quot;, &quot;10&quot;, &quot;2&quot;, y &quot;3&quot;). Buscamos la ubicación del primer punto: &lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;size_t i = ver.find('.');&lt;br /&gt;&lt;br /&gt;if (i != std::string::npos)&lt;br /&gt;  std::printf(&quot;El punto fue encontrado en la posición %d\n&quot;, i);&lt;br /&gt;else&lt;br /&gt;  std::printf(&quot;No hay punto en la cadena\n&quot;);&lt;br /&gt;&lt;/pre&gt;Ejecutando el código anterior, deberíamos obtener el mensaje: &lt;br /&gt;&lt;pre&gt;El punto fue encontrado en la posición 1&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;¿Qué es &lt;a href=&quot;http://www.cplusplus.com/reference/clibrary/cstring/size_t/&quot;&gt;size_t&lt;/a&gt;?&lt;/b&gt; Es como el tipo &quot;unsigned int&quot;, el tipo de dato retornado por el operador &lt;a href=&quot;http://www.cppreference.com/wiki/keywords/sizeof&quot;&gt;sizeof()&lt;/a&gt; y utilizado como índice en las funciones de std::string.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;¿Qué es &lt;a href=&quot;http://www.cplusplus.com/reference/string/string/npos/&quot;&gt;std::string::npos&lt;/a&gt;?&lt;/b&gt; Es el máximo valor posible de un &lt;em&gt;size_t&lt;/em&gt; y se utiliza para indicar (en este caso) que la función &lt;em&gt;find&lt;/em&gt; falló (no encontró el punto).&lt;br /&gt;&lt;br /&gt;Una vez que tenemos la posición del punto, podemos obtener la porción de texto que contiene la primer cifra, para eso usamos la función miembro &lt;a href=&quot;http://www.cplusplus.com/reference/string/string/substr/&quot;&gt;substr&lt;/a&gt;: &lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;std::string primer_cifra = ver.substr(0, i);&lt;br /&gt;&lt;/pre&gt;Esto significa: &lt;em&gt;che vos, función substr, devolveme el pedazo de cadena de caracteres que va desde el índice 0, y tiene una longitud de i-caracteres.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;El proceso puede ser repetido tantas veces como queramos para seguir obteniendo cifras. Por ejemplo, para la siguiente cifra debemos buscar (find) el siguiente punto, pero comenzando desde el que encontramos hace un rato: &lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;i++;     // ir a la posición siguiente del punto '.'&lt;br /&gt;size_t j = ver.find('.', i);&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;¿Qué es (o hace) el segundo argumento de find?&lt;/b&gt; Le indica a la función desde donde debe comenzar a buscar. La primera vez que usamos find este argumento no se especificó, porque por omisión toma el valor 0, es decir, buscar desde el inicio de la cadena.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;¿Por qué i++?&lt;/b&gt; Porque si comenzáramos a buscar un punto desde &lt;em&gt;i&lt;/em&gt;, nos devolvería la misma posición &lt;em&gt;i&lt;/em&gt; (porque justamente, en &lt;em&gt;i&lt;/em&gt;, está el primer punto que encontramos). Entonces debemos avanzar una posición.&lt;br /&gt;&lt;br /&gt;Ahora, debemos recortar la segunda cifra: &lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;std::string segunda_cifra = ver.substr(i, j-i);&lt;br /&gt;&lt;/pre&gt;La segunda cifra, comienza desde &lt;em&gt;i&lt;/em&gt; y tiene una longitud igual a &lt;em&gt;j-i&lt;/em&gt;. Para comprender esto, vea la siguiente figura:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;155&quot; src=&quot;std_string_indices.png&quot; /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;De esta forma, &lt;em&gt;ver.substr(i, j-i)&lt;/em&gt; nos devuelve la cadena &quot;10&quot;. La versión completa del algoritmo puede quedar algo así:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;vector&amp;gt;  // Por std::vector&lt;br /&gt;#include &amp;lt;string&amp;gt;  // Por std::string&lt;br /&gt;#include &amp;lt;cstdlib&amp;gt; // Por std::strtol&lt;br /&gt;#include &amp;lt;cstdio&amp;gt;  // Por std::printf&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  std::string ver = &quot;1.10.2.3&quot;;&lt;br /&gt;&lt;br /&gt;  // Vector con cada cifra.&lt;br /&gt;  // Luego del procesamiento esto debería ser = { 1, 10, 2, 3 }&lt;br /&gt;  std::vector&amp;lt;int&amp;gt; cifras;&lt;br /&gt;&lt;br /&gt;  size_t i = 0;   // Comenzamos desde i=0&lt;br /&gt;  size_t j = 0;&lt;br /&gt;&lt;br /&gt;  // Repetir hasta no llegar al final de la cadena&lt;br /&gt;  while (j != std::string::npos) {&lt;br /&gt;    // Buscar próximo punto&lt;br /&gt;    j = ver.find('.', i);&lt;br /&gt;&lt;br /&gt;    std::string cifra;&lt;br /&gt;&lt;br /&gt;    // Si se encontró un punto&lt;br /&gt;    if (j != std::string::npos) {&lt;br /&gt;      // Recortamos desde i hasta j&lt;br /&gt;      cifra = ver.substr(i, j-i);&lt;br /&gt;&lt;br /&gt;      // El nuevo comienzo para buscar puntos será &quot;j+1&quot;&lt;br /&gt;      i = j+1;&lt;br /&gt;    }&lt;br /&gt;    // Si no se encontró un punto&lt;br /&gt;    else {&lt;br /&gt;      // Recortamos desde &quot;i&quot; hasta el final de la cadena&lt;br /&gt;      cifra = ver.substr(i);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // Obtener el valor entero de la cifra&lt;br /&gt;    int cifra_int = std::strtol(cifra.c_str(), NULL, 10);&lt;br /&gt;&lt;br /&gt;    // Agregar la cifra al vector&lt;br /&gt;    cifras.push_back(cifra_int);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  for (size_t i=0; i&amp;lt;cifras.size(); ++i)&lt;br /&gt;    printf(&quot;cifras[%d] = %d\n&quot;, i, cifras[i]);&lt;br /&gt;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;La salida del anterior programa es:&lt;br /&gt;&lt;pre&gt;cifras[0] = 1&lt;br /&gt;cifras[1] = 10&lt;br /&gt;cifras[2] = 2&lt;br /&gt;cifras[3] = 3&lt;br /&gt;&lt;/pre&gt;Con este código, podríamos implementar una clase &quot;Version&quot; con la siguiente interfaz:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;class Version&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;  Version(const char*);&lt;br /&gt;  Version(const std::string&amp;amp;);&lt;br /&gt;&lt;br /&gt;  bool operator==(const Version&amp;amp; u) const;&lt;br /&gt;  bool operator&amp;lt;(const Version&amp;amp; u) const;&lt;br /&gt;  // ...&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;En un próximo post voy a colocar una posible implementación de la clase &quot;Version&quot;.
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Punteros por ámbito (scoped pointers)</title>
   <link href="http://dacap.com.ar/blog/cpp/punteros-por-ambito-scoped-pointers"/>
   <updated>2009-11-06T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/punteros-por-ambito-scoped-pointers</id>
   <content type="html">&lt;div class='post'&gt;
C++ no tiene un &lt;a href=&quot;http://es.wikipedia.org/wiki/Recolector_de_basura&quot;&gt;recolector de basura&lt;/a&gt;, &lt;a href=&quot;http://www.research.att.com/~bs/C++0xFAQ.html#gc-abi&quot;&gt;aunque C++0x le va tomando el gustito&lt;/a&gt;, tenemos algunas opciones para liberarnos de liberar memoria, valga la redundancia.&lt;br /&gt;&lt;br /&gt;Imaginemos un código como el siguiente:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;cstdio&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class A {&lt;br /&gt;public:&lt;br /&gt;  A()         { printf(&quot;A\n&quot;);    }&lt;br /&gt;  ~A()        { printf(&quot;~A\n&quot;);   }&lt;br /&gt;  void hola() { printf(&quot;hola\n&quot;); }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  A* a = new A;&lt;br /&gt;  a-&amp;gt;hola();&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;El anterior programa, por más &lt;a href=&quot;http://en.wikipedia.org/wiki/Minimalism&quot;&gt;minimalista&lt;/a&gt; que parezca, tiene un &lt;a href=&quot;http://en.wikipedia.org/wiki/Memory_leak&quot;&gt;memory leak&lt;/a&gt;. Aunque los &lt;a href=&quot;http://en.wikipedia.org/wiki/Resource_(computer_science)&quot;&gt;recursos&lt;/a&gt; suelen ser liberados por el mismo sistema operativo al finalizar el programa, si el proceso se ejecuta por mucho tiempo (e.j. un servicio que se ejecuta por días, semanas o meses dentro de un servidor), los recursos se van agotando poco a poco hasta que la computadora queda hecha una &lt;a href=&quot;http://es.wikipedia.org/wiki/Pasa&quot;&gt;pasa&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Para arreglar el leak, deberíamos escribir:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;int main()&lt;br /&gt;{&lt;br /&gt;  A* a = new A;&lt;br /&gt;  a-&amp;gt;hola();&lt;br /&gt;  &lt;b&gt;delete a;&lt;/b&gt;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;¿Cómo hacemos para liberar memoria sin llamar &lt;i&gt;delete&lt;/i&gt; nosotros mismos?&lt;/b&gt; Podemos crear una clase utilitaria que haga el trabajo por nosotros en su destructor. Por ejemplo, en el siguiente código veremos que el delete es llamado en el destructor de PunteroA:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;class PunteroA {&lt;br /&gt;  A* ptr;&lt;br /&gt;public:&lt;br /&gt;  PunteroA(A* p) { ptr = p; }&lt;br /&gt;  &lt;b&gt;~PunteroA()    { delete ptr; }&lt;/b&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  PunteroA a(new A);&lt;br /&gt;  a-&amp;gt;hola();          // error, &quot;a&quot; no es un puntero ni sobrecarga operator-&amp;gt;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;El anterior programa nos dará un error de compilación ya que el tipo PunteroA no soporta el operador flecha. Debemos agregarlo en la definición de la clase PunteroA:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;class PunteroA {&lt;br /&gt;  A* ptr;&lt;br /&gt;public:&lt;br /&gt;  PunteroA(A* p)  { ptr = p; }&lt;br /&gt;  ~PunteroA()     { delete ptr; }&lt;br /&gt;  &lt;b&gt;A* operator-&amp;gt;() { return ptr; }&lt;/b&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  PunteroA a(new A);&lt;br /&gt;  a-&amp;gt;hola();        // ahora sí, PunteroA::operator-&amp;gt;() nos devuelve&lt;br /&gt;                    // el verdadero puntero A* y A::hola() finalmente&lt;br /&gt;                    // es llamado&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;¿Cómo obtengo el A* desde un PunteroA?&lt;/b&gt; Debemos definir el operador de conversión hacia A*:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;class PunteroA {&lt;br /&gt;  A* ptr;&lt;br /&gt;public:&lt;br /&gt;  PunteroA(A* p)  { ptr = p; }&lt;br /&gt;  ~PunteroA()     { delete ptr; }&lt;br /&gt;  A* operator-&amp;gt;() { return ptr; }&lt;br /&gt;  &lt;b&gt;operator A*()   { return ptr; }&lt;/b&gt;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;Así podemos usar un PunteroA en funciones que reciban un A*. Ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;void func(A* a) { ... }&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  PunteroA a(new A);&lt;br /&gt;  func(a);&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;Generalizando:&lt;/b&gt; Podemos generalizar nuestro PunteroA para cualquier tipo de dato:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;template&amp;lt;class T&amp;gt;&lt;br /&gt;class ScopedPointer {&lt;br /&gt;  T* ptr;&lt;br /&gt;public:&lt;br /&gt;  ScopedPointer(T* p) { ptr = p; }&lt;br /&gt;  ~ScopedPointer()    { delete ptr; }&lt;br /&gt;  &lt;br /&gt;  operator T*()       { return ptr; }&lt;br /&gt;  T* operator-&amp;gt;()     { return ptr; }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;Así podemos usar el mismo ScopedPointer para liberar instancias de cualquier clase:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;int main()&lt;br /&gt;{&lt;br /&gt;  ScopedPointer&amp;lt;A&amp;gt; a(new A);&lt;br /&gt;  ScopedPointer&amp;lt;B&amp;gt; b(new B);&lt;br /&gt;  a-&amp;gt;hola();&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;¿Y si quiero liberar otro tipo de recurso?&lt;/b&gt; Si el recurso no es memoria, y es liberado con otra función en vez de delete, podemos generalizar nuestro ScopedPointer con un nuevo parámetro de template llamado &lt;i&gt;Destroyer&lt;/i&gt;:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;struct DefaultDestroyer {&lt;br /&gt;  template&amp;lt;class T&amp;gt;&lt;br /&gt;  static void &lt;b&gt;free&lt;/b&gt;(T* ptr) { delete ptr; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template&amp;lt;class T, class &lt;b&gt;Destroyer&lt;/b&gt; = DefaultDestroyer&amp;gt;&lt;br /&gt;class ScopedPointer {&lt;br /&gt;  T* ptr;&lt;br /&gt;public:&lt;br /&gt;  ScopedPointer(T* p) { ptr = p; }&lt;br /&gt;  ~ScopedPointer()    { &lt;b&gt;Destroyer::free(ptr);&lt;/b&gt; }&lt;br /&gt;  &lt;br /&gt;  operator T*()       { return ptr; }&lt;br /&gt;  T* operator-&amp;gt;()     { return ptr; }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;En este caso, el destructor ~ScopedPointer llama a la función estática Destroyer::free. Esta función básicamente puede hacer lo que nosotros queramos. Podría ser útil para liberar ficheros o cualquier otro tipo de recurso:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;struct FileDestroyer {&lt;br /&gt;  static void free(FILE* ptr) { fclose(ptr); }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  ScopedPointer&amp;lt;FILE, FileDestroyer&amp;gt; file(fopen(&quot;hola.txt&quot;, &quot;rt&quot;));&lt;br /&gt;  char buf[256];&lt;br /&gt;  fread(buf, 1, 256, file);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;¿No existen punteros de este tipo ya implementados?&lt;/b&gt; &lt;a href=&quot;http://www.boost.org/&quot;&gt;Boost&lt;/a&gt; tiene su propio &lt;a href=&quot;http://www.boost.org/doc/libs/1_40_0/libs/smart_ptr/scoped_ptr.htm&quot;&gt;scoped_ptr&lt;/a&gt;. También existen punteros más avanzados que cuentan referencias, como los &lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B0x#General-purpose_smart_pointers&quot;&gt;smart pointers&lt;/a&gt;.
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Interfaces vs. Conceptos</title>
   <link href="http://dacap.com.ar/blog/cpp/interfaces-vs-conceptos"/>
   <updated>2009-10-18T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/interfaces-vs-conceptos</id>
   <content type="html">&lt;div class='post'&gt;
¿Qué son los conceptos? Vamos a ver con un simple ejemplo, cómo podemos hacer una equivalencia entre las conocidas &lt;a href=&quot;http://en.wikipedia.org/wiki/Interface_(computer_science)&quot;&gt;interfaces&lt;/a&gt; y los &lt;a href=&quot;http://en.wikipedia.org/wiki/Concept_(generic_programming)&quot;&gt;conceptos&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Imaginen esta &quot;interfaz&quot; (clase abstracta):&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;class IPortero {&lt;br /&gt;public:&lt;br /&gt;  virtual IPortero() { }&lt;br /&gt;  virtual void ir_a_piso(int piso) = 0;&lt;br /&gt;  virtual int piso_destino() = 0;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;Tenemos otra clase Ascensor que podemos &quot;personalizar&quot; con nuestro propio portero, así nuestra implementación de portero puede hacer &lt;a href=&quot;http://es.wikipedia.org/wiki/Ascensor#Algoritmos_de_Maniobras&quot;&gt;lo que se le de la gana&lt;/a&gt;:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;class Ascensor {&lt;br /&gt;  IPortero* m_portero;&lt;br /&gt;public:&lt;br /&gt;  Ascensor(IPortero* portero) {&lt;br /&gt;    m_portero = portero;&lt;br /&gt;  }&lt;br /&gt;  void apretaron_boton_en_piso(int piso) {&lt;br /&gt;    m_portero-&gt;ir_a_piso(piso);&lt;br /&gt;    mover_ascensor(m_portero-&gt;piso_destino());&lt;br /&gt;  }&lt;br /&gt;  void mover_ascensor(int piso) { ... }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;Con programación genérica, podemos reformular la interfaz convirtiéndola en un &quot;concepto&quot; y la clase Ascensor en una clase plantilla:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;template&amp;lt;class TipoPortero&amp;gt;&lt;br /&gt;class Ascensor {&lt;br /&gt;  TipoPortero m_portero;&lt;br /&gt;public:&lt;br /&gt;  Ascensor() { }&lt;br /&gt;  void apretaron_boton_en_piso(int piso) {&lt;br /&gt;    m_portero.ir_a_piso(piso);&lt;br /&gt;    mover_ascensor(m_portero.piso_destino());&lt;br /&gt;  }&lt;br /&gt;  void mover_ascensor(int piso) { ... }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;La pregunta es, &lt;em&gt;¿qué demonios es TipoPortero?&lt;/em&gt;. La respuesta es sencilla: TipoPortero puede ser cualquier tipo de dato que cumpla los siguientes requisitos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Tenga un constructor por omisión (que se pueda construir un nuevo TipoPortero sin argumentos, o sea, &lt;em&gt;TipoPortero()&lt;/em&gt;).&lt;br /&gt;&lt;li&gt;Tenga una función miembro &lt;em&gt;TipoPortero::ir_a_piso(int)&lt;/em&gt;, la cual recibe un &quot;int&quot; (o cualquier tipo de dato que se pueda construir desde un &quot;int&quot; implícitamente).&lt;br /&gt;&lt;li&gt;Y otra función miembro &lt;em&gt;TipoPortero::piso_destino()&lt;/em&gt; que devuelve un entero.&lt;br /&gt;&lt;/ul&gt;&lt;p&gt;&lt;b&gt;¿Cómo especificamos la &quot;interfaz&quot; o los &quot;requerimientos&quot; de un concepto?&lt;/b&gt; Sencillamente no se puede, &lt;a href=&quot;http://cmasomenos.blogspot.com/2009/07/c0x-no-va-tener-conceptos.html&quot;&gt;C++0x iba a soportar esto&lt;/a&gt;, pero ya no. Hoy en día la mejor respuesta es usar algunos comentarios en la clase Ascensor que especifiquen qué espera en sus parámetros de template. En este aspecto se podría decir que IPortero es mejor porque especifica explícitamente lo que el portero tiene que hacer (funciones a implementar, etc.).&lt;p&gt;&lt;b&gt;¿Qué ventaja tiene el concepto con respecto a las interfaces?&lt;/b&gt; La clase genérica Ascensor ahora tiene el mismo portero adentro suyo (no un puntero a la interfaz). Las llamadas a las funciones miembro &lt;em&gt;ir_a_piso&lt;/em&gt; y &lt;em&gt;piso_destino&lt;/em&gt; son llamadas directas (no tienen el &lt;a href=&quot;http://en.wikipedia.org/wiki/Virtual_method_table#Efficiency&quot;&gt;overhead de una llamada a una función virtual&lt;/a&gt;).
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Clases que "desaparecen" luego de compilar</title>
   <link href="http://dacap.com.ar/blog/cpp/clases-que-desaparecen-luego-de-compilar"/>
   <updated>2009-10-17T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/clases-que-desaparecen-luego-de-compilar</id>
   <content type="html">&lt;div class='post'&gt;
La magia de C++ es que, una vez compilado el código, algunas clases pueden desaparecer por completo (principalmente las que se usan en &lt;a href=&quot;http://en.wikipedia.org/wiki/Call_stack&quot;&gt;stack&lt;/a&gt;). O sea, aunque las clases abstraen al programador de los detalles de implementación, al final, el código termina siendo tan óptimo como si la clase no fuera utilizada en un principio.&lt;br /&gt;&lt;br /&gt;Un ejemplo. Teniendo la siguiente clase Acumulador:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;cstdio&amp;gt;&lt;br /&gt;&lt;br /&gt;class Acumulador {&lt;br /&gt;  int v;&lt;br /&gt;public:&lt;br /&gt;  Acumulador()         { v = 0;                   }&lt;br /&gt;  ~Acumulador()        { std::printf(&quot;%d\n&quot;, v);  }&lt;br /&gt;  void acumular(int x) { v += x;                  }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;Un código como el siguiente:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;{&lt;br /&gt;  Acumulador acum;&lt;br /&gt;  acum.acumular(2);&lt;br /&gt;  acum.acumular(4);&lt;br /&gt;  acum.acumular(10);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Al compilarlo (optimizándolo), el código equivale a exactamente esto:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;{&lt;br /&gt;  int v = 0;&lt;br /&gt;  v += 2;&lt;br /&gt;  v += 4;&lt;br /&gt;  v += 10;&lt;br /&gt;  std::printf(&quot;%d\n&quot;, v);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;La clase Acumulador ya no existe. Obtenemos el código más óptimo posible: sin llamadas a la función &quot;acumular&quot;, ni ningún byte extra de memoria (Acumulador ocupa lo mismo de memoria que ocupa un &quot;int&quot;).&lt;br /&gt;&lt;br /&gt;Este ejemplo no ayuda a ver grandes ventajas, pero si el constructor y el destructor hacen tareas complicadas, y las funciones miembros también, el resultado puede llevarnos a dos puntos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Nos abstrae de la complejidad de la implementación (e.j. &lt;em&gt;para qué quiero saber cómo se acumula si sólo quiero acumular&lt;/em&gt;)&lt;br /&gt;&lt;li&gt;Obtenemos código tan óptimo como si no hubiéramos usado la abstracción (e.j. &lt;em&gt;las operaciones se acercan al hardware tanto como sea posible&lt;/em&gt;).&lt;br /&gt;&lt;/ul&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>SourceForge habla de Allegro Sprite Editor</title>
   <link href="http://dacap.com.ar/blog/meta/sourceforge-habla-de-allegro-sprite-editor"/>
   <updated>2009-10-13T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/meta/sourceforge-habla-de-allegro-sprite-editor</id>
   <content type="html">&lt;p&gt;Hoy salió &lt;a href='https://sourceforge.net/community/allegro-con-spirito-a-graphics-editor-for-sprites/'&gt;un artículo&lt;/a&gt; sobre &lt;a href='http://www.aseprite.org/'&gt;Allegro Sprite Editor&lt;/a&gt; en la SourceForge Community.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Las viejas home pages</title>
   <link href="http://dacap.com.ar/blog/meta/las-viejas-home-pages"/>
   <updated>2009-10-07T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/meta/las-viejas-home-pages</id>
   <content type="html">&lt;p&gt;&lt;em&gt;(Una nota que nadie nunca leerá)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Viendo &lt;a href='http://dacap.com.ar'&gt;mi página&lt;/a&gt; hoy en día, siento que ya es una reliquia. Hace muchísimo que las páginas personales dejaron de existir como eran antes. Ahora son todos blogs, feeds, artículos, noticias, etc. Las viejas páginas personales (con secciones, site-map, etc.) ya son una antigüedad.&lt;/p&gt;

&lt;p&gt;A lo largo de los años fui quitando más y más texto de mi página, hasta dejarla pelada completamente. Hoy en día son sólo links, apuntando a otros sitios para bajarse cosas útiles (¿?). Algún que otro párrafo explicando algo, pero inclusive sospecho que esos párrafos nunca serán leídos.&lt;/p&gt;

&lt;p&gt;En fin, las viejas páginas personales fueron devoradas por la &amp;#8220;fast-food&amp;#8221; de la información en Internet.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Google Wave</title>
   <link href="http://dacap.com.ar/blog/tech/google-wave"/>
   <updated>2009-09-19T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/tech/google-wave</id>
   <content type="html">&lt;p&gt;Una de las mejores cosas que vi:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://wave.google.com/'&gt;http://wave.google.com/&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/Google_Wave'&gt;http://en.wikipedia.org/wiki/Google_Wave&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://code.google.com/intl/es-AR/apis/wave/'&gt;http://code.google.com/intl/es-AR/apis/wave/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Editado 2012-04-05&lt;/strong&gt;: Ja, me causa gracia hoy en día como una de las mejores cosas que pense ver, la cerraron.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Modernización de Emacs</title>
   <link href="http://dacap.com.ar/blog/emacs/modernizacion-de-emacs"/>
   <updated>2009-08-26T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/emacs/modernizacion-de-emacs</id>
   <content type="html">&lt;p&gt;&lt;a href='http://xahlee.org/emacs/modernization.html'&gt;Un artículo&lt;/a&gt; de Xah Lee que habla sobre cómo mejorar Emacs. Por fin alguien que piensa en la usabilidad en el software libre.&lt;/p&gt;

&lt;p&gt;Y su proyecto para llevarlo a cabo: &lt;a href='http://www.ergoemacs.org/'&gt;ErgoEmacs&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Lo que quieras hacer</title>
   <link href="http://dacap.com.ar/blog/music/lo-que-quieras-hacer"/>
   <updated>2009-07-23T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/music/lo-que-quieras-hacer</id>
   <content type="html">&lt;p&gt;Tema &lt;em&gt;Lo que quieras hacer&lt;/em&gt; de &lt;em&gt;Riff&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Te dicen que nunca hiciste algo bien,
que no fuiste lo que debías ser;
no saben que acaso no quisiste ser,
como ellos decían estaba bien.

Según pasa el tiempo te das cuenta que
todo fue distinto a lo que iba a ser,
sólo queda ahora seguir adelante,
seguir adelante y no retroceder.

Tuya, es toda tu vida
para hacer lo que tu quieras hacer,
tuya, y no sólo mía
porque yo ya no te puedo ni ver.&lt;/code&gt;&lt;/pre&gt;
&lt;iframe allowfullscreen='' frameborder='0' height='315' src='http://www.youtube.com/embed/fKoSMBg3WeM' width='560'&gt;
&lt;/iframe&gt;</content>
 </entry>
 
 <entry>
   <title>C++0x no va a tener "conceptos"</title>
   <link href="http://dacap.com.ar/blog/cpp/cpp0x-no-va-a-tener-conceptos"/>
   <updated>2009-07-23T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/cpp0x-no-va-a-tener-conceptos</id>
   <content type="html">&lt;div class='post'&gt;
En la última reunión del &lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/&quot;&gt;ISO C++ Standards Committe&lt;/a&gt;e decidieron quitar los &quot;&lt;a href=&quot;http://en.wikipedia.org/wiki/Concepts_%28C%2B%2B0x%29&quot;&gt;conceptos&lt;/a&gt;&quot; del próximo estándar de &lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B0x&quot;&gt;C++&lt;/a&gt; (que en realidad, en vez de C++0x va a ser C++1x y chirola). &lt;a href=&quot;http://www.ddj.com/architect/218600111&quot;&gt;Un artículo de Bjarne Stroustrup&lt;/a&gt; habla al respecto:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;[...] Básicamente, los &quot;conceptos&quot; tenían como meta hacer de la programación genérica algo más accesible a la mayoría de los programadores, pero esa meta ha sido para mí (Stroustrup) seriamente comprometida: En vez de hacer la programación genérica más accesible, los &quot;conceptos&quot; se fueron convirtiendo en otra herramienta más en las manos de los expertos (únicamente).&lt;br /&gt;[...]&lt;br /&gt;Para resumir y de alguna forma simplificar, he afirmado que:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Los &quot;conceptos&quot; como están actualmente definidos son muy difíciles de utilizar, lo que los llevará al desuso, dando la posibilidad a un desuso de los &lt;em&gt;templates&lt;/em&gt; mismos y a la adopción completa de C++0x.&lt;/li&gt;&lt;li&gt;Un pequeño conjunto de simplificaciones [&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2906.pdf&quot;&gt;BS2009&lt;/a&gt;] pueden dejar a los &quot;conceptos&quot; lo suficientemente aceptables como para salir acorde a las fechas planificadas para C++0x o con sólo un retraso menor.&lt;br /&gt;&lt;/ul&gt;[...] &lt;/blockquote&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>STL vector en vez de los clásicos buffers de C</title>
   <link href="http://dacap.com.ar/blog/cpp/stl-vector-en-vez-de-los-clasicos-buffers-de-c"/>
   <updated>2009-07-12T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/stl-vector-en-vez-de-los-clasicos-buffers-de-c</id>
   <content type="html">&lt;div class='post'&gt;
Algunas veces tenemos que crear buffers temporales. Por ejemplo, la función &lt;a href=&quot;http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/&quot;&gt;sprintf&lt;/a&gt; necesita de un buffer para poder dejar la cadena resultante. Ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;char buf[256];&lt;br /&gt;sprintf(buf, &quot;%d&quot;, 12345);&lt;br /&gt;// usar &quot;buf&quot;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Si queremos mantener el buffer en heap:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;char* buf = malloc(256);&lt;br /&gt;sprintf(buf, &quot;%d&quot;, 12345);&lt;br /&gt;// usar &quot;buf&quot;...&lt;br /&gt;free(buf);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;En C++ podríamos hacer uso de los operadores new[]/delete[]:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;char* buf = new char[256];&lt;br /&gt;sprintf(buf, &quot;%d&quot;, 12345);&lt;br /&gt;// usar &quot;buf&quot;...&lt;br /&gt;delete[] buf;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pero es aconsejable evitar la creación de arreglos con new[], y en su lugar hacer uso de &lt;a href=&quot;http://www.cplusplus.com/reference/stl/vector/&quot;&gt;std::vector&lt;/a&gt;:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;std::vector&amp;lt;char&amp;gt; buf(256);&lt;br /&gt;sprintf(&amp;amp;buf[0], &quot;%d&quot;, 12345);&lt;br /&gt;// usar &quot;&amp;amp;buf[0]&quot; en vez de &quot;buf&quot;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;El resultado: tenemos un buffer en el heap que se libera automáticamente (~std::vector) al salir del ámbito de la función que lo utiliza.
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Conscientemente, todo todo, lo podrás lograr</title>
   <link href="http://dacap.com.ar/blog/music/conscientemente-todo-todo-lo-podras-lograr"/>
   <updated>2009-04-06T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/music/conscientemente-todo-todo-lo-podras-lograr</id>
   <content type="html">&lt;p&gt;Tema &lt;em&gt;Conscientemente, todo todo, lo podrás lograr&lt;/em&gt; de &lt;em&gt;Billy Bond y La Pesada Del Rock and Roll&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;En tu mente, en tu mente vivirán.
Los deseos, los deseos de cambiar.
Concientemente todo todo lo podrás lograr.

No te quedes, no te quedes muy atrás.
Si no sigues, no tendrás con quien hablar.
Concientemente todo, todo lo podrás lograr.

Vamos chicos, vamos chicos a cambiar.
Vamos loco, vamos loco a cambiar.
Concientemente todo todo lo podrás lograr.

No te quedes siempre en el mismo lugar.
Vamos chico, vamos loco a cambiar.
Concientemente, todo todo, lo podrás lograr.&lt;/code&gt;&lt;/pre&gt;
&lt;iframe allowfullscreen='' frameborder='0' height='315' src='http://www.youtube.com/embed/bZYQLUkNJ9Q' width='420'&gt;
&lt;/iframe&gt;</content>
 </entry>
 
 <entry>
   <title>STL for each</title>
   <link href="http://dacap.com.ar/blog/cpp/stl-for-each"/>
   <updated>2009-03-21T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/stl-for-each</id>
   <content type="html">&lt;p&gt;Para recorrer un arreglo de C, podemos utilizar punteros. Comenzamos apuntando al primer elemento y frenamos una vez procesado el último elemento:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main()
{
  int array[] = { 5, 3, 4, 9, 1 };
  int array_size = sizeof(array) / sizeof(int); // cantidad de elementos de &amp;quot;array&amp;quot;
  int *array_begin = array;                     // comienzo del array
  int *array_end = array+array_size;            // final del array (+un elemento)
  int *it;                                      // el iterator

  for (it = array_begin;  it != array_end;  ++it) {
    printf(&amp;quot;%d\n&amp;quot;, *it);
  }
  return 0;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hay que tener en cuenta que &lt;code&gt;array_end&lt;/code&gt; es igual a &lt;code&gt;&amp;amp;array[5]&lt;/code&gt;. Sabiendo que sólo podemos acceder a los elementos desde &lt;code&gt;array[0]&lt;/code&gt; a &lt;code&gt;array[4]&lt;/code&gt;, decimos que &lt;code&gt;array[5]&lt;/code&gt; está más allá del último elemento del arreglo, es decir, &lt;code&gt;&amp;amp;array[5]&lt;/code&gt; es la posición de memoria que ya no es parte del mismo arreglo (de ahí &lt;code&gt;it != array_end&lt;/code&gt; significa &amp;#8220;mientras nos encontremos dentro del arreglo&amp;#8221;).&lt;/p&gt;

&lt;p&gt;¿Cómo recorrer un &lt;a href='http://www.sgi.com/tech/stl/Container.html'&gt;contenedor&lt;/a&gt; de la STL? La idea es similar, sólo que en vez de usar punteros utilizamos iteradores, y observe como la sintaxis del &lt;code&gt;for&lt;/code&gt; es exactamente la misma. (Nota: en este caso utilizamos un &lt;a href='http://www.sgi.com/tech/stl/Vector.html'&gt;vector&lt;/a&gt;.)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;

int main()
{
  vector&amp;lt;int&amp;gt; array;
  array.push_back(5);
  array.push_back(3);
  array.push_back(4);
  array.push_back(9);
  array.push_back(1);

  vector&amp;lt;int&amp;gt;::iterator it;

  for (it = array.begin();  it != array.end();  ++it) {
    cout &amp;lt;&amp;lt; *it &amp;lt;&amp;lt; endl;
  }
  return 0;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;¿Cómo recorrer un contenedor STL con el algoritmo &lt;a href='http://www.sgi.com/tech/stl/for_each.html'&gt;for_each&lt;/a&gt;? (Nota: Lo siguiente también se puede hacer con &lt;a href='http://www.sgi.com/tech/stl/copy.html'&gt;copy&lt;/a&gt; y &lt;a href='http://www.sgi.com/tech/stl/ostream_iterator.html'&gt;ostream_iterator&lt;/a&gt;.)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

void print_element(int a) { cout &amp;lt;&amp;lt; *it &amp;lt;&amp;lt; endl; }

int main()
{
  vector&amp;lt;int&amp;gt; array;
  array.push_back(5);
  array.push_back(3);
  array.push_back(4);
  array.push_back(9);
  array.push_back(1);

  for_each(array.begin(), array.end(), print_element);
  return 0;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;La función pasada como tercer parámetro a &lt;code&gt;for_each&lt;/code&gt; es llamada por cada elemento del arreglo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;template&amp;lt;typename InputIterator, typename Function&amp;gt;
Function for_each(InputIterator first, InputIterator last, Function f)
{
  for (; first != last; ++first)
    f(*first);
  return f;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;¿Por qué &lt;code&gt;for_each&lt;/code&gt; devuelve la función? Principalmente porque la función &lt;code&gt;f&lt;/code&gt; podría no ser una función! Podría ser un &lt;a href='http://www.sgi.com/tech/stl/functors.html'&gt;functor&lt;/a&gt; (objeto función), es decir, una instancia de una clase que tiene sobrecargado el &lt;code&gt;operator()&lt;/code&gt; (llamada a función). Pero este tema se merece su propio post.&lt;/p&gt;

&lt;p&gt;¿Se puede usar el algoritmo &lt;code&gt;for_each&lt;/code&gt; para los arreglos de C? Sí.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

void print_element(int a) { printf(&amp;quot;%d\n&amp;quot;, a); }

int main()
{
  int array[] = { 5, 3, 4, 9, 1 };
  int array_size = sizeof(array) / sizeof(int); // cantidad de elementos de &amp;quot;array&amp;quot;
  int *array_begin = array;                     // comienzo del array
  int *array_end = array+array_size;            // final del array (un elemento más)

  for_each(array_begin, array_end, print_element);
  return 0;
}&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>STL generate</title>
   <link href="http://dacap.com.ar/blog/cpp/stl-generate"/>
   <updated>2008-12-08T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/stl-generate</id>
   <content type="html">&lt;div class='post'&gt;
Si usted tiene una función que genera números/valores/instancias (ej: un generador de números aleatorios, o identificadores) puede usar el algoritmo &lt;a href=&quot;http://www.cplusplus.com/reference/algorithm/generate.html&quot;&gt;generate&lt;/a&gt; de la &lt;a href=&quot;http://www.sgi.com/tech/stl/&quot;&gt;STL&lt;/a&gt; para crear una secuencia de objetos. Por ejemplo, para generar 100 números (pseudo)aleatorios de 0 a 1:&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;#include &amp;lt;vector&amp;gt;&lt;br /&gt;&lt;br /&gt;double uniform_random()&lt;br /&gt;{&lt;br /&gt;  return (rand() % 10001) / 10000.0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  std::vector&amp;lt;double&amp;gt; v(100);&lt;br /&gt;  std::generate(v.begin(), v.end(), uniform_random);&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
El algoritmo &lt;em&gt;generate&lt;/em&gt; recibe dos iteradores (inicio y fin), y llama a la función especificada para cada una de las posiciones que recorre:&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;template&amp;lt;typename ForwardIterator, typename Generator&amp;gt;&lt;br /&gt;void generate(ForwardIterator first, ForwardIterator last,&lt;br /&gt;              Generator gen)&lt;br /&gt;{&lt;br /&gt;  for (; first != last; ++first)&lt;br /&gt;    *first = gen();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
Los algoritmos de la STL son genéricos porque utilizan la &lt;a href=&quot;http://en.wikipedia.org/wiki/Pointer_(computing)#C_and_C.2B.2B&quot;&gt;aritmética de punteros&lt;/a&gt;. Los iteradores sobrecargan los operadores para poder ser utilizados como punteros. Así un algoritmo puede ser utilizado con los contenedores de la STL (&lt;a href=&quot;http://www.sgi.com/tech/stl/Vector.html&quot;&gt;vector&lt;/a&gt;) o con los viejos y tan queridos arreglos (y punteros) de C:&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;&lt;br /&gt;double uniform_random()&lt;br /&gt;{&lt;br /&gt;  return (rand() % 10001) / 10000.0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  double v[100];&lt;br /&gt;  std::generate(v, v+100, uniform_random);&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>¿Preincrementar o postincrementar?</title>
   <link href="http://dacap.com.ar/blog/cpp/preincrementar-o-postincrementar"/>
   <updated>2008-08-19T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/preincrementar-o-postincrementar</id>
   <content type="html">&lt;div class='post'&gt;
Hace mucho que quería escribir un post tan inútil como este. La duda que siempre me pasaba por la cabeza era la siguiente: ¿Será exactamente el mismo código ensamblador el que genera el compilador cuando utilizamos el preincremento o el postincremento (sin utilizar el valor de retorno)? Tenía la seguridad de que así debía ser (una optimización tan básica no podía ser dejada de lado), pero me faltaban las pruebas (en ensamblador) para verificarlo.&lt;br /&gt;&lt;br /&gt;Recordando un poco, el preincremento&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;int a = 0;&lt;br /&gt;int b = ++a;&lt;br /&gt;&lt;/pre&gt;hace &lt;i&gt;a=1&lt;/i&gt; y &lt;i&gt;b=1&lt;/i&gt;, mientras que el postincremento&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;int a = 0;&lt;br /&gt;int b = a++;&lt;br /&gt;&lt;/pre&gt;hace &lt;i&gt;a=1&lt;/i&gt; y &lt;i&gt;b=0&lt;/i&gt;, esto significa que &lt;i&gt;b&lt;/i&gt; obtuvo el valor de &lt;i&gt;a&lt;/i&gt; anterior al incremento.&lt;br /&gt;&lt;br /&gt;Aquí &lt;i&gt;estamos utilizando&lt;/i&gt; el valor de retorno del operador incremento. El código ensamblador &lt;i&gt;es distinto&lt;/i&gt; para cada caso. Vamos a echarle una mirada (antes le recomiendo ver &lt;a href=&quot;http://www.unixwiz.net/techtips/win32-callconv-asm.html&quot;&gt;este excelente artículo&lt;/a&gt; para comprender más sobre el stack y las convenciones de llamadas). En el preincremento el código ensamblador (generado por GCC 3.4.5 para i386) es:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;subl  $8, %esp          // reservamos 8 bytes en el &lt;a href=&quot;http://en.wikipedia.org/wiki/Call_stack&quot;&gt;stack&lt;/a&gt; (para variables locales)&lt;br /&gt;movl  $0, -4(%ebp)      // a   = 0&lt;br /&gt;leal  -4(%ebp), %eax    // eax = &amp;amp;a&lt;br /&gt;incl  (%eax)            // *eax= (*eax) + 1&lt;br /&gt;movl  -4(%ebp), %eax    // eax = a&lt;br /&gt;movl  %eax, -8(%ebp)    // b   = eax&lt;br /&gt;&lt;/pre&gt;En el postincremento&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;subl  $8, %esp          // reservamos 8 bytes en el stack&lt;br /&gt;movl  $0, -4(%ebp)      // a   = 0&lt;br /&gt;movl  -4(%ebp), %edx    // edx = a&lt;br /&gt;leal  -4(%ebp), %eax    // eax = &amp;amp;a&lt;br /&gt;incl  (%eax)            // *eax= (*eax) + 1&lt;br /&gt;movl  %edx, -8(%ebp)    // b   = edx&lt;/pre&gt;donde se ve que el registro edx se utiliza para guardar el valor que tenía &lt;i&gt;a&lt;/i&gt; antes del incremento para luego asignárselo a &lt;i&gt;b&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Pero la pregunta original es, ¿qué pasa si &lt;b&gt;no&lt;/b&gt; usamos el valor de retorno? ¿el código de ++i o i++ es igual? Debería serlo, y de hecho, lo es. Pero como veremos más abajo, esto sólo se cumple si utilizamos tipos de datos &lt;i&gt;built-in&lt;/i&gt; (int, double, long, etc.). Miremos el siguiente código:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;void func() { }&lt;br /&gt;void pre () { for (int c=0; c&amp;lt;8; ++c) { func(); } }&lt;br /&gt;void post() { for (int c=0; c&amp;lt;8; c++) { func(); } }&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  pre();&lt;br /&gt;  post();&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Básico, un &lt;i&gt;for&lt;/i&gt; pero con las dos variantes posible de incremento. El código generado para ambos casos (tanto para la función &lt;i&gt;pre&lt;/i&gt; como &lt;i&gt;post&lt;/i&gt;) es el siguiente:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;  pushl %ebp              // guardar el viejo puntero a la base del stack&lt;br /&gt;  movl  %esp, %ebp        // establecer la nueva base del stack&lt;br /&gt;  subl  $4, %esp          // guardar 4 bytes en el stack (para variables locales)&lt;br /&gt;  movl  $0, -4(%ebp)      // c = 0&lt;br /&gt;L3:&lt;br /&gt;  cmpl  $7, -4(%ebp)&lt;br /&gt;  jg    L2                // si c &amp;gt; 7 entonces ir a L2&lt;br /&gt;  call  _func             // llamar a la función func()&lt;br /&gt;  leal  -4(%ebp), %eax    // eax = &amp;amp;c&lt;br /&gt;  incl  (%eax)            // *eax= (*eax) + 1&lt;br /&gt;  jmp   L3                // repetir yendo a L3&lt;br /&gt;L2:&lt;br /&gt;  leave                   // restaurar la base del stack (popl %ebp)&lt;br /&gt;  ret                     // retornar al punto de llamada&lt;br /&gt;&lt;/pre&gt;Realmente es indiferente usar cualquiera de los dos tipos de incremento, salvo, en los tipos definidos por el usuario.  C++ ofrece un soporte para tipos de usuario igual a los built-in (bueno, no del todo, pero &lt;a href=&quot;http://www.artima.com/cppsource/cpp0xP.html&quot;&gt;lo están solucionando&lt;/a&gt;). Nos da la posibilidad de sobrecargar los operadores de nuestros propios tipos (clases). Por ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;class tipo {&lt;br /&gt;  int x;&lt;br /&gt;public:&lt;br /&gt;  tipo(int y) : x(y) { }&lt;br /&gt;  tipo(const tipo&amp;amp; y) : x(y.x) { }&lt;br /&gt;  // preincremento&lt;br /&gt;  tipo&amp;amp; operator++() {&lt;br /&gt;    ++x;&lt;br /&gt;    return *this;&lt;br /&gt;  }&lt;br /&gt;  // postincremento&lt;br /&gt;  tipo operator++(int) {&lt;br /&gt;    tipo tmp(*this);&lt;br /&gt;    ++x;&lt;br /&gt;    return tmp;&lt;br /&gt;  }&lt;br /&gt;  bool operator&amp;lt;(int y) const { return x &amp;lt; y; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void func() { }&lt;br /&gt;void pre()  { for (tipo c=0; c&amp;lt;8; ++c) { func(); } }&lt;br /&gt;void post() { for (tipo c=0; c&amp;lt;8; c++) { func(); } }&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  post();&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;No colocaré el código ensamblador por desbordar belleza, pero el código generado en este caso es distinto: cada incremento llama a la función correspondiente a su operador. Esto es debido a que ambas implementaciones varían considerablemente. Por ejemplo, el postincremento necesita de una instancia extra de &lt;i&gt;tipo&lt;/i&gt; para poder devolver el anterior valor de &lt;i&gt;this&lt;/i&gt;, en cambio, el preincremento devuelve una referencia al mismo &lt;i&gt;this&lt;/i&gt; (sin necesidad de hacer una copia).&lt;br /&gt;&lt;br /&gt;Como dato curioso, algo interesante ocurre al utilizar las optimizaciones del GCC. Si compilamos este último programa con el parámetro -O3, vamos a ver que todas las funciones correspondientes a la clase &lt;i&gt;tipo&lt;/i&gt; desaparecen, y todo el código resultantes es &lt;i&gt;inline&lt;/i&gt;, dando como resultado un código tan óptimo como si hubiéramos utilizado un &lt;i&gt;int&lt;/i&gt; en vez de nuestra clase &lt;i&gt;tipo&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;¿Cómo obtengo el código ensamblador desde un archivo C/C++?&lt;/b&gt;&lt;br /&gt;Con el compilador &lt;i&gt;gcc&lt;/i&gt;, hay que utilizar el parámetro -S: &lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;g++ -S -o archivo.s -c archivo.cpp&lt;br /&gt;&lt;/pre&gt;En &lt;i&gt;archivo.s&lt;/i&gt; queda el código ensamblador (sintaxis &lt;a href=&quot;http://www.google.com.ar/search?q=AT%26T+Assembly+Syntax&quot;&gt;AT&amp;amp;T&lt;/a&gt;).
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Excepciones, RAII y auto_ptr</title>
   <link href="http://dacap.com.ar/blog/cpp/excepciones-raii-y-auto-ptr"/>
   <updated>2008-06-24T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/excepciones-raii-y-auto-ptr</id>
   <content type="html">&lt;div class='post'&gt;
Una de las mejores formas de realizar un control de errores es por medio de excepciones. Lamentablemente, si no se toman las precauciones adecuadas, se pueden obtener &lt;a href=&quot;http://en.wikipedia.org/wiki/Handle_leak&quot;&gt;leaks&lt;/a&gt; de algunos recursos. Por ejemplo, imagine el siguiente caso:&lt;pre class=&quot;prettyprint&quot;&gt;int main()&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;try {&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;char *ptr = new char[256];&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;double *matrix = new double[100000*100000]; // 74 Gigabytes&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;// ...&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;delete matrix;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;delete ptr;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;} catch (const std::bad_alloc&amp;amp; e) {&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;std::cout &amp;lt;&amp;lt; &quot;No hay memoria suficiente&quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;}&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Aquí, con el segundo &lt;em&gt;new&lt;/em&gt; una excepción &lt;em&gt;bad_alloc&lt;/em&gt; es lanzada. El problema es que la memoria asignada con el primer &lt;em&gt;new&lt;/em&gt; nadie la libera. Esto es un &lt;a href=&quot;http://en.wikipedia.org/wiki/Memory_leak&quot;&gt;memory leak&lt;/a&gt;. Una opción para solucionarlo es mediante un bloque &lt;a href=&quot;http://www.research.att.com/~bs/bs_faq2.html#finally&quot;&gt;finally&lt;/a&gt; &quot;a la Java&quot;:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;int main()&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;char *ptr = NULL;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;double *matrix = NULL;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;try {&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;ptr = new char[256];&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;matrix = new double[100000*100000];&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;// ...&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;delete matrix;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;delete ptr;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;} catch (...) { // finally&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;if (matrix) delete matrix;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;if (ptr) delete ptr;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;}&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Claro que esto no hace al manejo de errores una tarea transparente.&lt;br /&gt;&lt;br /&gt;En C++ se puede utilizar la técnica &lt;a href=&quot;http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization&quot;&gt;RAII&lt;/a&gt; (la adquisición de recursos está en la inicialización), lo que ayuda a evitar &lt;em&gt;leaks&lt;/em&gt;. La idea básica detrás de esto es que los constructores obtengan recursos, y los destructores los liberen. Al ocurrir una excepción, se van llamando los destructores de los objetos creados.&lt;br /&gt;&lt;br /&gt;Para solucionar nuestro problema, podemos utilizar la clase &lt;em&gt;auto_ptr&lt;/em&gt; que se encuentra en &amp;lt;memory&amp;gt;. Un &lt;em&gt;auto_ptr&lt;/em&gt; guarda un puntero que es liberado automáticamente en el destructor.&lt;pre class=&quot;prettyprint&quot;&gt;int main()&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;try {&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;std::auto_ptr&amp;lt;char&amp;gt; ptr(new char[256]);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;std::auto_ptr&amp;lt;double&amp;gt; matrix(new double[100000*100000]);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;// ...&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;} catch (const std::bad_alloc&amp;amp; e) {&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;std::cout &amp;lt;&amp;lt; &quot;No hay memoria suficiente&quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;}&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Los &lt;em&gt;delete&lt;/em&gt;s no son necesarios. Al salir del &lt;a href=&quot;http://en.wikipedia.org/wiki/Scope_%28programming%29&quot;&gt;ámbito&lt;/a&gt; del bloque &lt;em&gt;try&lt;/em&gt;, ya sea normalmente o por excepción, se llamará al destructor de los &lt;em&gt;auto_ptr&lt;/em&gt;s creados, así no se incurre en ningún tipo de &lt;em&gt;leak&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Advertencia&lt;/b&gt;: Los &lt;em&gt;auto_ptr&lt;/em&gt; deben ser utilizados sabiendo cuál es su verdadero funcionamiento: La copia de un &lt;em&gt;auto_ptr&lt;/em&gt; a otro no los deja equivalentes. La última copia se queda con el puntero, los demás lo van perdiendo, y el &lt;em&gt;delete&lt;/em&gt; lo invoca el último &lt;em&gt;auto_ptr&lt;/em&gt; destruido. Por ejemplo:&lt;pre class=&quot;prettyprint&quot;&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;std::auto_ptr&amp;lt;Persona&amp;gt; otra_persona;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;std::auto_ptr&amp;lt;Persona&amp;gt; una_persona(new Persona);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;otra_persona = una_persona;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;// ahora &quot;una_persona&quot; apunta a NULL&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;}&lt;br /&gt;} // aquí la persona es destruida&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Pregunta&lt;/b&gt;: ¿Por qué no usar objetos alojados en el &lt;a href=&quot;http://en.wikipedia.org/wiki/Call_stack&quot;&gt;stack&lt;/a&gt; en vez del &lt;a href=&quot;http://en.wikipedia.org/wiki/Dynamic_memory_allocation&quot;&gt;heap&lt;/a&gt; para evitar los &lt;em&gt;leaks&lt;/em&gt;? Porque el &lt;em&gt;stack&lt;/em&gt; es mucho más pequeño. Por ejemplo, el siguiente código provoca un &lt;a href=&quot;http://en.wikipedia.org/wiki/SIGSEGV&quot;&gt;SIGSEGV&lt;/a&gt; ya que el arreglo no entra en el &lt;em&gt;stack&lt;/em&gt;:&lt;pre class=&quot;prettyprint&quot;&gt;double matrix[1000000];&lt;/pre&gt;Pero sí entra en el &lt;em&gt;heap&lt;/em&gt;:&lt;pre class=&quot;prettyprint&quot;&gt;double *matrix = new double[1000000]; // 7.6 Megabytes&lt;/pre&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Compilando archivos</title>
   <link href="http://dacap.com.ar/blog/cpp/compilando-archivos"/>
   <updated>2008-05-10T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/compilando-archivos</id>
   <content type="html">&lt;div class='post'&gt;
Suponiendo que conoce qué es un archivo de &lt;a href=&quot;http://es.wikipedia.org/wiki/C%C3%B3digo_fuente&quot;&gt;código fuente&lt;/a&gt;, &lt;a href=&quot;http://es.wikipedia.org/wiki/C%C3%B3digo_objeto&quot;&gt;código objeto&lt;/a&gt;, un &lt;a href=&quot;http://es.wikipedia.org/wiki/Ejecutable&quot;&gt;ejecutable&lt;/a&gt; &lt;a href=&quot;http://es.wikipedia.org/wiki/EXE&quot;&gt;&lt;b&gt;.exe&lt;/b&gt;&lt;/a&gt;, y el &lt;a href=&quot;http://es.wikipedia.org/wiki/C%C3%B3digo_m%C3%A1quina&quot;&gt;código máquina&lt;/a&gt;; voy a pasar a explicar algunos comandos del &lt;a href=&quot;http://es.wikipedia.org/wiki/GCC&quot;&gt;GCC&lt;/a&gt; para compilar.&lt;br /&gt;&lt;br /&gt;Retomando la idea del &lt;a href=&quot;http://cmasomenos.blogspot.com/2008/03/medir-el-tiempo-de-una-rutina.html&quot;&gt;anterior post&lt;/a&gt;, imagínese que creamos un archivo &lt;a href=&quot;http://davidcapello.googlepages.com/timemark.h&quot;&gt;timemark.h&lt;/a&gt; para darle un poco de portabilidad a todo este asunto de medir el desempeño de una rutina. Las declaraciones de timemark.h pueden ser usadas para crear un pequeño programa &lt;a href=&quot;http://davidcapello.googlepages.com/ejemplo1.c&quot;&gt;ejemplo1.c&lt;/a&gt; que sea independiente de la plataforma (por lo menos entre Windows y GNU/Linux).&lt;br /&gt;&lt;br /&gt;Vamos a probar algunas operaciones sobre la línea de comandos para ver cómo compilar este archivo. Inicialmente, la opción más sencilla es utilizar directamente &quot;gcc ejemplo1.c&quot;, esto nos da como resultado el archivo &quot;a.exe&quot; o &quot;a.out&quot;. Veamos (teniendo &lt;em&gt;timemark.h&lt;/em&gt; y &lt;em&gt;ejemplo1.c&lt;/em&gt; en un directorio &lt;em&gt;C:\ejemplo1&lt;/em&gt;):&lt;br /&gt;&lt;pre class=&quot;source-code&quot;&gt;C:\ejemplo1&amp;gt;gcc ejemplo1.c&lt;br /&gt;C:/Temp/ccMjdaaa.o:ejemplo1.c:(.text+0x31): undefined reference to `get_timemark'&lt;br /&gt;C:/Temp/ccMjdaaa.o:ejemplo1.c:(.text+0x3c): undefined reference to `get_timemark'&lt;br /&gt;C:/Temp/ccMjdaaa.o:ejemplo1.c:(.text+0x4e): undefined reference to `timemark_diff'&lt;br /&gt;collect2: ld returned 1 exit status&lt;br /&gt;&lt;/pre&gt;Como podrá ver, recibimos un error por las funciones no definidas &lt;em&gt;get_timermark&lt;/em&gt; y &lt;em&gt;timemark_diff&lt;/em&gt;. Esto se debe a que utilizando solamente &quot;gcc ejemplo1.c&quot;, se intenta enlazar el código de ese único archivo en el ejecutable. Tenemos algunas opciones intermedias antes de crear el .exe final. Por ejemplo, podemos crear un archivo que contenga el código objeto ya compilado (pero únicamente del archivo en cuestión &lt;em&gt;ejemplo1.c&lt;/em&gt;):&lt;br /&gt;&lt;pre class=&quot;source-code&quot;&gt;C:\ejemplo1&amp;gt;gcc -o ejemplo1.o -c ejemplo1.c&lt;br /&gt;&lt;/pre&gt;Así obtenemos el &lt;em&gt;ejemplo1.o&lt;/em&gt; (código objeto). En este caso no recibimos errores ya que &lt;em&gt;ejemplo1.o&lt;/em&gt; hace referencias a las funciones &lt;em&gt;get_timermark&lt;/em&gt; y &lt;em&gt;timemark_diff&lt;/em&gt;, pero no necesita su implementación específica. Cuando creamos el ejecutable final (&lt;em&gt;.exe&lt;/em&gt;) es cuando realmente necesitamos el código de todas las funciones invocadas.&lt;br /&gt;&lt;br /&gt;El archivo que falta es &lt;a href=&quot;http://davidcapello.googlepages.com/timemark.c&quot;&gt;timemark.c&lt;/a&gt;. Del mismo modo, podemos compilarlo con el comando:&lt;br /&gt;&lt;pre class=&quot;source-code&quot;&gt;C:\ejemplo1&amp;gt;gcc -o timemark.o -c timemark.c&lt;br /&gt;&lt;/pre&gt;Ahora resta unir ambos archivos objetos en un único ejecutable, con un único punto de acceso (&lt;em&gt;main&lt;/em&gt;):&lt;br /&gt;&lt;pre class=&quot;source-code&quot;&gt;C:\ejemplo1&amp;gt;gcc -o ejemplo.exe ejemplo1.o timemark.o&lt;br /&gt;&lt;/pre&gt;Y listo. Por ahora, lo aprendido son estos dos comandos:&lt;br /&gt;&lt;pre class=&quot;source-code&quot;&gt;gcc -o archivo.o -c archivo.c&lt;br /&gt;gcc -o archivo.exe archivo1.o archivo2.o archivo3.o ...&lt;br /&gt;&lt;/pre&gt;El primero compila el código fuente para generar un archivo objeto, y el segundo comando reune (enlaza, &lt;em&gt;linkea&lt;/em&gt;) el grupo de archivos objetos en un ejecutable único.&lt;br /&gt;&lt;br /&gt;De todas formas, es bastante tedioso escribir estos comandos cada vez que queremos compilar. Para resolver el problema podemos utilizar los llamados Makefiles. Claro, lo más interesante queda para un futuro post.
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Medir el tiempo de una rutina</title>
   <link href="http://dacap.com.ar/blog/cpp/medir-el-tiempo-de-una-rutina"/>
   <updated>2008-03-01T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/medir-el-tiempo-de-una-rutina</id>
   <content type="html">&lt;div class='post'&gt;
¿Alguna vez se preocupó por la velocidad con la que corre su programa? ¿No? Entonces usted es un candidato perfecto para jugar al &lt;a href=&quot;http://en.wikipedia.org/wiki/Java_%28board_game%29&quot;&gt;Java&lt;/a&gt;. En caso contrario, voy a explicarle un pequeño código que utilizaremos en próximas entregas para medir el tiempo de ejecución de determinadas rutinas.&lt;br /&gt;&lt;br /&gt;Ya lo dijo &lt;a href=&quot;http://shreevatsa.wordpress.com/2008/05/16/premature-optimization-is-the-root-of-all-evil/&quot;&gt;alguien&lt;/a&gt;: &quot;La optimización prematura es la raíz de todos los males&quot;. No hay nada más cierto, aunque también es verdad que hacer algo simple de la peor forma posible, es la causa de &lt;a href=&quot;http://www.urbandictionary.com/define.php?term=pain+in+the+ass&quot;&gt;otros grandes males&lt;/a&gt;. Con esto quiero decir que debería intentar hacer las cosas de la forma más simple y más óptima que usted conozca (dándole mayor importancia a la simplicidad del código); luego se preocupa por &quot;darle velocidad&quot; a la rutina que provoca el cuello de botella (en próximos posts veremos cómo usar &lt;em&gt;gprof&lt;/em&gt; para detectarlo).&lt;br /&gt;&lt;br /&gt;La forma de calcular el tiempo de CPU que toma una función es muy simple:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;tomamos el valor del reloj antes de realizar la llamada (&lt;em&gt;t_ini&lt;/em&gt;),&lt;/li&gt;&lt;li&gt;llamamos a la rutina en cuestión, y&lt;/li&gt;&lt;li&gt;tomamos nuevamente el valor del reloj (&lt;em&gt;t_fin&lt;/em&gt;).&lt;/li&gt;&lt;/ul&gt;La diferencia entre &lt;em&gt;t_fin - t_ini&lt;/em&gt; nos da el total de tiempo que tomó: 1) hacer la llamada a la rutina, 2) que esta haga su trabajo, 3) que devuelva el resultado.&lt;br /&gt;&lt;br /&gt;Ahora hay algunos pequeños detalles de implementación. Por ejemplo, ¿qué función usar para tomar el tiempo del reloj? Y más importante, ¿qué precisión obtenemos con dicha función?&lt;br /&gt;&lt;br /&gt;Para tomar el tiempo podemos usar la rutina &lt;a href=&quot;http://www.cplusplus.com/clock&quot;&gt;clock()&lt;/a&gt;, que devuelve el tiempo &lt;em&gt;aproximado&lt;/em&gt; de CPU que transcurrió desde que nuestro programa fue iniciado, dicho tiempo representado en un valor de tipo &lt;a href=&quot;http://www.cplusplus.com/clock_t&quot;&gt;clock_t&lt;/a&gt;: un valor entero que indica una cantidad de &quot;tics&quot; de reloj.&lt;br /&gt;&lt;br /&gt;La precisión que tenemos con dicha rutina es de &lt;a href=&quot;http://www.cplusplus.com/CLOCKS_PER_SEC&quot;&gt;CLOCKS_PER_SEC&lt;/a&gt; (tics de reloj por segundo), lo que significa que por cada segundo que pasa, la función &lt;em&gt;clock()&lt;/em&gt; nos devolverá CLOCKS_PER_SEC unidades más que el valor anterior. En MinGW, CLOCKS_PER_SEC es igual a 1000, pero es mejor no fiarse de esto, ya que en otras plataformas dicho valor varía. Inclusive, según POSIX, la constante CLOCKS_PER_SEC debería ser 1000000.&lt;br /&gt;&lt;br /&gt;Veamos algo de código:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;time.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;clock_t t_ini, t_fin;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;double secs;&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;t_ini = clock();&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;/* ...hacer algo... */&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;t_fin = clock();&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;secs = (double)(t_fin - t_ini) / CLOCKS_PER_SEC;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;printf(&quot;%.16g milisegundos\n&quot;, secs * 1000.0);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Con esto podemos medir cuántos milisegundos demoró &lt;em&gt;&quot;hacer algo&quot;&lt;/em&gt;. Todo parece muy bonito hasta que nos damos cuenta de dos grandes problemas:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Tomar una medida única y aislada es igual que tomar un número completamente aleatorio y mostrarlo (no es una &lt;a href=&quot;http://es.wikipedia.org/wiki/Muestra_estad%C3%ADstica&quot;&gt;muestra representativa&lt;/a&gt;). Es mejor repetir las mediciones unas cuantas veces (y hablo del orden de las 100, o 100000, o 1e32 veces), y luego sacar un promedio de todo.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;La función &lt;span style=&quot;font-style: italic;&quot;&gt;clock()&lt;/span&gt; no llega a tener una precisión  ni de 10 milisegundos (aunque CLOCS_PER_SEC sea 1000 o más).&lt;/li&gt;&lt;/ol&gt;Una vez dicho esto, el código de arriba no sirve ni para &lt;a href=&quot;http://es.wikipedia.org/wiki/Papel_higi%C3%A9nico&quot;&gt;limpiarse&lt;/a&gt; los &lt;a href=&quot;http://es.wikipedia.org/wiki/Traste&quot;&gt;trastes&lt;/a&gt;... Así que tenemos que buscar una función con mayor precisión, y además, promediar varias muestras.&lt;br /&gt;&lt;br /&gt;Existen otras alternativas como la función &lt;a href=&quot;http://www.freebsd.org/cgi/man.cgi?query=gettimeofday&quot;&gt;gettimeofday&lt;/a&gt;, pero bajo Windows sufre del mismo problema de precisión que &lt;em&gt;clock()&lt;/em&gt;. Igualmente en Linux funciona perfectamente, así que vale la pena tener en cuenta este código:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;time.h&amp;gt;&lt;br /&gt;#include &amp;lt;sys/time.h&amp;gt;&lt;br /&gt;&lt;br /&gt;/* retorna &quot;a - b&quot; en segundos */&lt;br /&gt;double timeval_diff(struct timeval *a, struct timeval *b)&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;(double)(a-&amp;gt;tv_sec + (double)a-&amp;gt;tv_usec/1000000) -&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;(double)(b-&amp;gt;tv_sec + (double)b-&amp;gt;tv_usec/1000000);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;struct timeval t_ini, t_fin;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;double secs;&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;gettimeofday(&amp;amp;t_ini, NULL);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;/* ...hacer algo... */&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;gettimeofday(&amp;amp;t_fin, NULL);&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;secs = timeval_diff(&amp;amp;t_fin, &amp;amp;t_ini);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;printf(&quot;%.16g milliseconds\n&quot;, secs * 1000.0);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Como puede ver la estructura &lt;em&gt;timeval&lt;/em&gt; contiene dos campos, segundos y microsegundos transcurridos (tv_sec y tv_usec respectivamente), por lo tanto ofrece una precisión de microsegundos. De todas formas, como decía esto en Windows no sirve y la razón es sencilla, en la misma &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms725496%28VS.85%29.aspx&quot;&gt;MSDN&lt;/a&gt; explican que el temporizador del sistema corre aproximadamente a unos 10 milisegundos, por lo tanto, cualquier función que lo utilice nos estará dando la misma asquerosa precisión (inclusive al utilizar &lt;a href=&quot;http://www.google.com.ar/search?q=GetSystemTimeAsFileTime+msdn&quot;&gt;GetSystemTimeAsFileTime&lt;/a&gt; y &lt;a href=&quot;http://www.google.com.ar/search?q=FILETIME+msdn&quot;&gt;FILETIME&lt;/a&gt;). Por lo tanto la solución es utilizar lo que se conoce en el mundo de Windows como el &quot;contador de rendimiento de alta resolución&quot; (&lt;em&gt;high-resolution performance counter&lt;/em&gt;):&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;windows.h&amp;gt;&lt;br /&gt;&lt;br /&gt;/* retorna &quot;a - b&quot; en segundos */&lt;br /&gt;double performancecounter_diff(LARGE_INTEGER *a, LARGE_INTEGER *b)&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;LARGE_INTEGER freq;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;QueryPerformanceFrequency(&amp;amp;freq);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return (double)(a-&amp;gt;QuadPart - b-&amp;gt;QuadPart) / (double)freq.QuadPart;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;LARGE_INTEGER t_ini, t_fin;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;double secs;&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;QueryPerformanceCounter(&amp;amp;t_ini);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;/* ...hacer algo... */&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;QueryPerformanceCounter(&amp;amp;t_fin);&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;secs = performancecounter_diff(&amp;amp;t_fin, &amp;amp;t_ini);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;printf(&quot;%.16g milliseconds\n&quot;, secs * 1000.0);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return 0;&lt;br /&gt;}&lt;/pre&gt;En este caso, imagine que &lt;a href=&quot;http://www.google.com.ar/search?q=QueryPerformanceCounter+msdn&quot;&gt;QueryPerformanceCounter&lt;/a&gt; es como &lt;em&gt;clock()&lt;/em&gt; y &lt;a href=&quot;http://www.google.com.ar/search?q=QueryPerformanceFrequency+msdn&quot;&gt;QueryPerformanceFrequency&lt;/a&gt; es como CLOCKS_PER_SEC. Es decir, la primera función nos da el valor del contador, y la segunda su frecuencia (en ciclos por segundo, &lt;a href=&quot;http://en.wikipedia.org/wiki/Hertz&quot;&gt;hertz&lt;/a&gt;). Cabe aclarar que un &lt;a href=&quot;http://www.google.com.ar/search?q=LARGE_INTEGER+msdn&quot;&gt;LARGE_INTEGER&lt;/a&gt; es una forma de representar un entero de 64 bits por medio de una unión (&lt;em&gt;union&lt;/em&gt;).&lt;br /&gt;&lt;br /&gt;Como tarea al lector, si es que existe alguno, le queda hacer una versión &quot;portable&quot; (entre Windows y Linux) para medir el rendimiento (con unos cuantos &lt;em&gt;#ifdef WIN32&lt;/em&gt; y &lt;em&gt;#endif&lt;/em&gt; sería suficiente).&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;18 de Marzo del 2008&lt;/span&gt;: acá transcribo una macro que me pasó el amigo &lt;a href=&quot;http://www.carlosbecker.com.ar/&quot;&gt;Carlos Becker&lt;/a&gt; para medir el tiempo de una rutina en Linux mediante &lt;a href=&quot;http://www.tin.org/bin/man.cgi?section=3&amp;topic=clock_gettime&quot;&gt;clock_gettime&lt;/a&gt;:&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;#define TIME_THIS(X)                                         \
  {                                                          \
    struct timespec ts1, ts2;                                \
    clock_gettime( CLOCK_REALTIME, &amp;amp;ts1 );                   \
    X;                                                       \
    clock_gettime( CLOCK_REALTIME, &amp;amp;ts2 );                   \
    printf( #X &quot; demora: %f\n&quot;,                              \
      (float) ( 1.0*(1.0*ts2.tv_nsec - ts1.tv_nsec*1.0)*1e-9 \
      + 1.0*ts2.tv_sec - 1.0*ts1.tv_sec ) );                 \
  }

/* podemos usarla así */
{
  double x, y, z;
  x = 2.0;
  y = 4.0;
  TIME_THIS(z = sqrt(x*x + y*y));
}
&lt;/pre&gt;Lo que da como resultado:
&lt;pre class=&quot;prettyprint&quot;&gt;z = sqrt(x*x + y*y) demora: 0.015164
&lt;/pre&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Conseguir un compilador</title>
   <link href="http://dacap.com.ar/blog/cpp/conseguir-un-compilador"/>
   <updated>2008-02-17T00:00:00-03:00</updated>
   <id>hhttp://dacap.com.ar/blog/cpp/conseguir-un-compilador</id>
   <content type="html">&lt;div class='post'&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;b&gt;Editado 21 de mayo 2011&lt;/b&gt;: Este post se encuentra aquí sólo a fines históricos, ahora usted puede usar el &lt;a href=&quot;http://sourceforge.net/projects/mingw/files/Automated%20MinGW%20Installer/mingw-get-inst&quot;&gt;instalador automático de MinGW&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;&lt;b&gt;Editado 9 de septiembre 2010&lt;/b&gt;: Aunque este post contiene información útil de cómo instalar MinGW con gcc 3.4, tal vez prefiera antes probar este &lt;a href=&quot;http://cmasomenos.blogspot.com/2010/06/descargar-mingw-con-gcc-45.html&quot;&gt;nuevo post sobre cómo descargar MinGW con gcc 4.5 de forma automática&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;En este blog vamos a hablar sobre los lenguajes de programación C y C++, y cómo usar software GNU para hacer aplicaciones. También voy a tratar de investigar algo de ensamblador.&lt;br /&gt;&lt;p&gt;De todas formas, para evitar hacer un primer post completamente inútil &quot;de presentación&quot;, voy a pasar a explicarles cómo pueden instalar un compilador gratuito en Windows desde cero, y hacer un pequeño programa &lt;span style=&quot;font-style: italic;&quot;&gt;&quot;Hola Mundo&quot;&lt;/span&gt; sin pensar mucho (eso sí, van a tener que leer un poco). El proceso para Linux es más sencillo, ya que el compilador suele venir instalado por defecto en la mayoría de las distribuciones.&lt;br /&gt;&lt;p&gt;Primero, algunas definiciones importantes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://www.mingw.org/&quot; style=&quot;font-weight: bold;&quot;&gt;MinGW&lt;/a&gt;: Un conjunto de programas y bibliotecas que permiten crear aplicaciones para Windows.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://gcc.gnu.org/&quot; style=&quot;font-weight: bold;&quot;&gt;GCC&lt;/a&gt;: El compilador. Transforma código escrito en C/C++ a un archivo ejecutable (.exe). En realidad hace miles de maravillas más, pero por ahora nos vamos a quedar con esta definición.&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;MSYS&lt;/span&gt;: Es un conjunto mínimo de programas para poder ejecutar scripts &lt;span style=&quot;font-style: italic;&quot;&gt;&quot;a la&quot;&lt;/span&gt; Unix. Además incluye una terminal que emula un pequeño entorno GNU/Linux.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://www.gnu.org/software/emacs/&quot; style=&quot;font-weight: bold;&quot;&gt;Emacs&lt;/a&gt;: La madre de los editores de texto. Alguna vez dije que era una porquería o muy complicado, y que conviene usar editores como el &lt;a href=&quot;http://sourceforge.net/projects/rhide&quot;&gt;RHIDE&lt;/a&gt; o &lt;a href=&quot;http://setedit.sourceforge.net/&quot;&gt;Setedit&lt;/a&gt;. Bueno, la cosa es que con &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;un poco&lt;/span&gt;&quot; de práctica uno comprende el poder de esta herramienta.&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;make&lt;/span&gt;: Un programa que puede compilar muchos archivos y linkearlos en un ejecutable de forma automatizada (siempre y cuando le escribamos un archivo con las órdenes adecuadas). Generalmente los programadores están acostumbrados a utilizar un &lt;a href=&quot;http://es.wikipedia.org/wiki/Entorno_de_desarrollo_integrado&quot;&gt;IDE&lt;/a&gt; (como el &lt;a href=&quot;http://www.bloodshed.net/devcpp.html&quot;&gt;DevC++&lt;/a&gt;) que maneje el proyecto, calcule las dependencias entre archivos, compile todo lo necesario, linkee, ejecute y depure. Si bien esto es cómodo, espero poder enseñarles a automatizar la compilación y liberarlos de un determinado IDE para compilar los programas.&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;cmd.exe&lt;/span&gt;: Es la línea de comandos de Windows. Si nunca lo utilizó, es hora que se ponga a usarlo. Para iniciar la línea de comandos debe ir al menú &quot;Inicio/Ejecutar...&quot; e introducir &quot;cmd&quot;. ¿Cómo se usa? Bueno, &lt;a href=&quot;http://www.google.com.ar/search?q=introduccion+al+shell+de+comandos+cmd.exe&quot;&gt;empiece a buscar...&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Ahora nos dedicaremos a instalar el MinGW, para eso debe comenzar a bajarse los siguientes archivos (si no sabe &lt;a href=&quot;http://www.7-zip.org/&quot;&gt;cómo descomprimir un archivo .tar.gz...&lt;/a&gt;):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/mingw-runtime-3.13.tar.gz?download&quot;&gt;mingw-runtime-3.13.tar.gz&lt;/a&gt;: Los archivos de cabecera y bibliotecas estándares (stdio.h, math.h, libc, libm, etc.)    &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/w32api-3.10.tar.gz?download&quot;&gt;w32api-3.10.tar.gz&lt;/a&gt;: Archivos de cabecera del API de Win32&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/gcc-core-3.4.5-20060117-1.tar.gz?download&quot;&gt;gcc-core-3.4.5-20060117-1.tar.gz&lt;/a&gt;: El preprocesador de C y el compilador de C&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/gcc-g++-3.4.5-20060117-1.tar.gz?download&quot;&gt;gcc-g++-3.4.5-20060117-1.tar.gz&lt;/a&gt;: El compilador de C++ y los archivos de cabecera de C++&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/binutils-2.17.50-20060824-1.tar.gz?download&quot;&gt;binutils-2.17.50-20060824-1.tar.gz&lt;/a&gt;: Varios programas utilitarios que sirve para diferentes propósitos (ej: quitar símbolos de depuración con &lt;span style=&quot;font-style: italic;&quot;&gt;strip&lt;/span&gt;, convertir direcciones a líneas de código fuente con &lt;span style=&quot;font-style: italic;&quot;&gt;addr2line&lt;/span&gt;, procesar la información de &lt;a href=&quot;http://en.wikipedia.org/wiki/Performance_analysis&quot;&gt;rendimiento&lt;/a&gt; con &lt;span style=&quot;font-style: italic;&quot;&gt;gprof&lt;/span&gt;, crear librerías con &lt;span style=&quot;font-style: italic;&quot;&gt;ar&lt;/span&gt;, compilar los archivos de recursos de Windows con &lt;span style=&quot;font-style: italic;&quot;&gt;windres&lt;/span&gt;, etc.).&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/mingw32-make-3.81-2.tar.gz?download&quot;&gt;mingw32-make-3.81-2.tar.gz&lt;/a&gt;: La utilidad &lt;span style=&quot;font-style: italic;&quot;&gt;make&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/gdb-5.2.1-1.exe?download&quot;&gt;gdb-5.2.1-1.exe&lt;/a&gt;: El depurador de código&lt;/li&gt;&lt;/ul&gt;Una vez que consiga todos estos archivos, debe crear una carpeta C:\MinGW (le recomiendo esa ubicación) y descomprimir todo ahí mismo. Para instalar el depurador (gdb) deberá ejecutar el instalador, seguir los pasos, y colocar como carpeta de instalación &quot;C:\MinGW&quot;.&lt;br /&gt;&lt;p&gt;Una vez instalado todo, usted ya está en condiciones para compilar código en C o C++. Antes verifique que en dicha carpeta tiene una estructura de directorios como la siguiente:&lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;C:\MinGW&lt;br /&gt;  bin\&lt;br /&gt;  doc\&lt;br /&gt;  include\&lt;br /&gt;  info\&lt;br /&gt;  lib\&lt;br /&gt;  libexec\&lt;br /&gt;  man\&lt;br /&gt;  mingw32\&lt;br /&gt;&lt;/pre&gt;Si así es, significa que todo salió bien (bueno, tampoco descomprimir unos archivos es algo tan complicado).&lt;br /&gt;&lt;p&gt;Para estar seguros que el compilador funcione, vamos a crear el programa de prueba por excelencia, el &quot;Hola Mundo&quot;. Abra el bloc de notas (Inicio/Ejecutar/notepad) y escriba en un archivo el siguiente código:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;  printf(&quot;Hola Mundo\n&quot;);&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Guarde el archivo como &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;C:\MinGW\hola.c&lt;/span&gt;&quot;. Ahora abra la línea de comandos &lt;span style=&quot;font-weight: bold;&quot;&gt;cmd.exe&lt;/span&gt;, y ahí mismo ejecute los siguientes comandos:&lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;cd C:\MinGW&lt;br /&gt;set PATH=C:\MinGW\bin;%PATH%&lt;br /&gt;gcc hola.c&lt;br /&gt;&lt;/pre&gt;Verá que el archivo &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;a.exe&lt;/span&gt;&quot; se crea en el directorio C:\MinGW. Si ejecuta el programa &lt;span style=&quot;font-weight: bold;&quot;&gt;a.exe&lt;/span&gt; visualizará en la salida de la consola el mensaje más estúpido jamás escrito: &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;Hola Mundo&lt;/span&gt;&quot;&lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;C:\MinGW&amp;gt;a.exe&lt;br /&gt;Hola Mundo&lt;br /&gt;&lt;/pre&gt;A continuación le paso a explicar qué hicimos en esta ráfaga de pasos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&quot;cd C:\MinGW&quot; es para ubicarnos en el directorio donde se encuentra el archivo o proyecto que queremos compilar (si no sabía esto, es porque todavía no estuvo buscando cómo usar cmd.exe...).&lt;/li&gt;&lt;li&gt;&quot;set PATH=C:\MinGW\bin;%PATH%&quot; es un conjunto de varias cosas: &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;PATH&lt;/span&gt;&quot; es una variable de entorno que indica cuáles son los directorios donde podemos encontrar archivos ejecutables (archivos ejecutables como &lt;span style=&quot;font-style: italic;&quot;&gt;gcc.exe&lt;/span&gt;, &lt;span style=&quot;font-style: italic;&quot;&gt;cpp.exe&lt;/span&gt;, etc.); &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;set&lt;/span&gt;&quot; es un comando del shell para cambiar el valor de una variable de entorno; y &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;%PATH%&lt;/span&gt;&quot; devuelve el valor de dicha variable de entorno. Por lo tanto, lo único que estamos haciendo aquí es agregar una nueva ruta (C:\MinGW\bin) a PATH para que el shell encuentre los archivos ejecutables que a nosotros nos interesa (el preprocesador, compilador, etc.). Si desea ver dónde busca el shell los archivos ejecutables actualmente, puede usar el siguiente comando: &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;echo %PATH%&lt;/span&gt;&quot;&lt;/li&gt;&lt;li&gt;&quot;gcc hola.c&quot; compila el programa &quot;hola.c&quot; y deja el resultado (&lt;span style=&quot;font-style: italic;&quot;&gt;linkea&lt;/span&gt; o &lt;span style=&quot;font-style: italic;&quot;&gt;linkedita&lt;/span&gt;) en un archivo llamado &quot;a.exe&quot; (o &quot;a.out&quot; en Linux). En otros posts veremos cómo podemos especificar un nombre distinto a este archivo de salida.&lt;/li&gt;&lt;/ul&gt;De todo lo visto, lo más molesto es la configuración de la variable de entorno, es decir, si pensamos compilar varias veces, cada vez que abramos un shell (cmd.exe) deberemos hacer un &quot;set PATH=C:\MinGW\bin;%PATH%&quot;. Para evitar este paso tenemos dos opciones:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Si tiene accesos de Administrador, puede hacer click derecho sobre &quot;Mi PC&quot;, &quot;Propiedades&quot;, &quot;Opciones Avanzadas&quot;, &quot;Variables de Entorno&quot; y modificar la variable PATH agregándole el valor &quot;C:\MinGW\bin&quot; (recuerde no tocar las demás rutas, además de agregar un &quot;;&quot; para separar las distintas rutas entre sí).&lt;/li&gt;&lt;li&gt;En otro caso, puede crearse un archivo de comandos por lotes mi-mingw.bat para iniciar el shell adecuadamente con el PATH ya configurado. Por ejemplo, un mi-mingw.bat posible podría ser:&lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;set PATH=C:\MinGW\bin;%PATH%&lt;br /&gt;start cmd.exe&lt;br /&gt;&lt;/pre&gt;Este archivo podemos dejarlo en el Escritorio y cada vez que tengamos ganas de compilar, con un simple doble click ya podemos empezar. Inclusive, en vez de iniciar &quot;start cmd.exe&quot; podríamos iniciar algún IDE o editor de texto como Emacs. Pero eso para otro post.&lt;/li&gt;&lt;/ol&gt;Bueno, por hoy me cansé. Cualquier problema o pregunta que tengan, los comentarios están abiertos (y bien moderados :)
&lt;/div&gt;
</content>
 </entry>
 

</feed>
