<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ilikeblues &#187; C/C++</title>
	<atom:link href="http://blog.ilikeblues.com/category/software/cc/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ilikeblues.com</link>
	<description>Mind your Software</description>
	<lastBuildDate>Wed, 28 Jul 2010 12:56:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<atom:link rel="next" href="http://blog.ilikeblues.com/category/software/cc/feed/?page=2" />

		<item>
		<title>VT6656 Driver para Ubuntu Karmic Koala</title>
		<link>http://blog.ilikeblues.com/2009/11/vt6656-driver-para-ubuntu-karmic-koala/</link>
		<comments>http://blog.ilikeblues.com/2009/11/vt6656-driver-para-ubuntu-karmic-koala/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 12:18:30 +0000</pubDate>
		<dc:creator>ilikeblues</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Trucos]]></category>
		<category><![CDATA[driver vt6656]]></category>
		<category><![CDATA[driver vt6656 ubuntu]]></category>
		<category><![CDATA[driver vt6656 ubuntu karmic]]></category>
		<category><![CDATA[driver vt6656 ubuntu karmic koala]]></category>
		<category><![CDATA[vt6656]]></category>
		<category><![CDATA[vt6656 karmic]]></category>
		<category><![CDATA[vt6656 karmic koala]]></category>

		<guid isPermaLink="false">http://blog.ilikeblues.com/?p=170</guid>
		<description><![CDATA[Tal como sugieren en el thread del bug correspondiente, VT6656 wireless chipset is unsupported, la solución para conseguir que funcione la tarjeta (o adaptador USB) wifi con chipset VT6656 es compilar la versión &#8220;staging&#8221; del driver, incluído en la versión del kernel 2.6.32-rc6.
En mi último viaje a Japón compré un Kohjinsha SC3 que monta este [...]


Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2010/03/aplicacion-offline-para-iphone/' rel='bookmark' title='Permanent Link: Aplicación Offline para iPhone'>Aplicación Offline para iPhone</a></li>
<li><a href='http://blog.ilikeblues.com/2008/05/configuracion-proxy-en-ubuntu/' rel='bookmark' title='Permanent Link: Configuración proxy en Ubuntu'>Configuración proxy en Ubuntu</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Tal como sugieren en el thread del bug correspondiente, <a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/162671">VT6656 wireless chipset is unsupported</a>, la solución para conseguir que funcione la tarjeta (o adaptador USB) wifi con chipset VT6656 es compilar la versión &#8220;staging&#8221; del driver, incluído en la versión del <a href="http://www.kernel.org/pub/linux/kernel/v2.6/testing/linux-2.6.32-rc6.tar.bz2">kernel 2.6.32-rc6</a>.</p>
<p>En mi último <a href="http://viajes.ilikeblues.com/fotos/japan-04-09/">viaje a Japón</a> compré un Kohjinsha SC3 que monta este chipset. Así que he generado un pequeño paquete que permite compilar e instalar el driver en <a href="http://www.ubuntu.com">Ubuntu 9.10 (Karmic Koala)</a>.</p>
<p>Podéis descargar los fuentes aquí:</p>
<p><a href="http://blog.ilikeblues.com/wp-content/uploads/driver_staging_vt6656.tgz">driver_staging_vt6656.tgz</a></p>
<p>Al descomprimirlo generará una carpeta llamada &#8220;driver&#8221;. Basta con hacer (dentro de la carpeta generada):</p>
<pre class="brush: php">
$ sudo make install
</pre>
<p>para que se añada el driver al arranque de Ubuntu. Si ejecutamos:</p>
<pre class="brush: php">
$ modprobe vntwusb
</pre>
<p>el driver se cargará y podremos conectar a la red usando nuestra tarjeta wifi con chipset VT6656.</p>
<p>Por último decir que, tal como indican en el <a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/162671">thread relacionado con el bug</a>, <strong>sólo funciona la encriptación WPA2. No funcionan ni WPA ni la mixta (WPA+WPA2)</strong>.</p>
<p>Que lo disfrutéis.</p>


<p>Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2010/03/aplicacion-offline-para-iphone/' rel='bookmark' title='Permanent Link: Aplicación Offline para iPhone'>Aplicación Offline para iPhone</a></li>
<li><a href='http://blog.ilikeblues.com/2008/05/configuracion-proxy-en-ubuntu/' rel='bookmark' title='Permanent Link: Configuración proxy en Ubuntu'>Configuración proxy en Ubuntu</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.ilikeblues.com/2009/11/vt6656-driver-para-ubuntu-karmic-koala/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C++: excepción en construtor o destructor</title>
		<link>http://blog.ilikeblues.com/2009/01/c-excepcion-en-construtor-o-destructor/</link>
		<comments>http://blog.ilikeblues.com/2009/01/c-excepcion-en-construtor-o-destructor/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 09:29:55 +0000</pubDate>
		<dc:creator>ilikeblues</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[auto_ptr]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[constructor]]></category>
		<category><![CDATA[destructor]]></category>

		<guid isPermaLink="false">http://blog.ilikeblues.com/?p=75</guid>
		<description><![CDATA[Cuando un constructor de clase lanza una excepción, los destructores para todos los objetos locales (objetos que forman parte de la clase que se está construyendo) son llamados. Si uno de los destructores llamados lanza una excepción, el método terminate será ejecutado.
En general, no se debería lanzar una excepción durante la ejecución de un constructor [...]


Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2010/07/diferencia-entre-classnotfoundexception-y-noclassdeffounderror/' rel='bookmark' title='Permanent Link: Diferencia entre ClassNotFoundException y NoClassDefFoundError'>Diferencia entre ClassNotFoundException y NoClassDefFoundError</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Cuando un constructor de clase lanza una excepción, los destructores para todos los objetos locales (objetos que forman parte de la clase que se está construyendo) son llamados. Si uno de los destructores llamados lanza una excepción, el método <strong>terminate</strong> será ejecutado.</p>
<p>En general, no se debería lanzar una excepción durante la ejecución de un constructor sin hacer un <strong>catch</strong> de la misma y llevar a acabo una <em>&#8220;limpieza&#8221;</em> de los recursos utilizados por la clase. Una solución sencilla podría ser utilizar el constructor por defecto para crear los miembros <em>&#8220;seguros&#8221;</em> de la clase y después llamar a un método de inicialización para los <em>&#8220;no seguros&#8221;</em>, incluyendo el <strong>exception handling</strong> en éste.</p>
<p>Veamos un ejemplo sencillo. Supongamos que tenemos el siguiente código:</p>
<pre class="brush: cpp">
class Employee {
   ...
   Image * m_pImage;
   AudioClip * m_pAudio;
};

Employee(..., string image, string audio) : ..., m_pImage(NULL), m_pAudio(NULL)
{
   ...
   m_pImage = new Image(image);
   m_pAudio = new AudioClip(audio); // throw point
}
</pre>
<p>Si el código &#8220;new AudioClip(audio)&#8221; lanza una excepción, el flujo de control sale del constructor y se produce un memory leak. El destructor sólo sería llamado si el objeto hubiera sido completamente construido, pero no ha sido así.</p>
<p>Entonces, la manera correcta de implementar ese constructor sería:</p>
<p class="Program">
<pre class="brush: cpp">
Employee(..., string image, string audio) : ..., m_pImage(NULL), m_pAudio(NULL)
{
   ...
   try {
      m_pImage = new Image(image);
      m_pAudio = new AudioClip(audio);
   }
   catch(...)
   {
      delete m_pImage;
      delete m_pAudio;
      throw;
   }
}
</pre>
<p>De manera que, si se levanta una excepción, los recursos reservados son liberados y se vuelve a despachar la excepción para que notificar al objeto que intentaba construir esta clase.</p>
<p>Esta solución es buena, funciona bien, excepto en el caso de que tengamos punteros constantes como miembros de la clase:</p>
<pre class="brush: cpp">
class Employee {
   ...
   Image * const m_pImage;
   AudioClip * const m_pAudio;
};
</pre>
<p>Estos miembros deben ser incializados por el incializador de miembros propio de la clase, donde no podemos poner bloques <em>try&#8230; catch</em>.</p>
<p>En este caso, podríamos utilizar la clase auto_ptr&lt;&gt; (o similar) como wrapper para los punteros, de manera que se conviertan en objetos locales a nuestra clase:</p>
<pre class="brush: cpp">
class Employee {
   ...
   auto_ptr&lt;image&gt; m_pImage;
   auto_ptr&lt;audioClip&gt; m_pAudio;
};
</pre>
<p>Como ya se ha dicho, si ocurre una excepción durante la ejecución del constructor, se ejecutan los destructores de todos los miembros locales a la clase. Es decir, se llamaría al destructor de auto_ptr&lt;&gt;, el cual libera, de la manera adecuada, todos los recursos reservados.</p>
<p>[Fuente: <a href="http://progtutorials.tripod.com/cpp2.htm#_Toc50821286">http://progtutorials.tripod.com</a>]</p>


<p>Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2010/07/diferencia-entre-classnotfoundexception-y-noclassdeffounderror/' rel='bookmark' title='Permanent Link: Diferencia entre ClassNotFoundException y NoClassDefFoundError'>Diferencia entre ClassNotFoundException y NoClassDefFoundError</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.ilikeblues.com/2009/01/c-excepcion-en-construtor-o-destructor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GNUmakefile para Objective-C y Objective-C++</title>
		<link>http://blog.ilikeblues.com/2008/12/gnumakefile-para-objective-c-y-objective-c/</link>
		<comments>http://blog.ilikeblues.com/2008/12/gnumakefile-para-objective-c-y-objective-c/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 14:09:52 +0000</pubDate>
		<dc:creator>ilikeblues</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://blog.ilikeblues.com/?p=70</guid>
		<description><![CDATA[Construir el makefile para un proyecto Objective-C en el framework de GNUstep es muy sencillo.
Basta con añadir algunas directivas de inclusión de ficheros y la lista de ficheros de código:

include $(GNUSTEP_MAKEFILES)/common.make

APP_NAME = edictParser
edictParser_APPLICATION_ICON = icon.png
edictParser_RESOURCE_FILES = icon.png
edictParser_OBJC_FILES = main.m

include $(GNUSTEP_MAKEFILES)/application.make

Para el caso de querer utilizar código C++, sustituimos la línea:

edictParser_OBJC_FILES = main.m

por:

edictParser_OBJCC_FILES = main.mm

Y un [...]


Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-para-obtencion-de-datos-de-cobertura-i/' rel='bookmark' title='Permanent Link: Utilización de gprof/gcov para obtención de datos de cobertura (I)'>Utilización de gprof/gcov para obtención de datos de cobertura (I)</a></li>
<li><a href='http://blog.ilikeblues.com/2008/02/llamadas-a-funciones-estaticas-externas-en-c/' rel='bookmark' title='Permanent Link: Llamadas a funciones estáticas externas en C'>Llamadas a funciones estáticas externas en C</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Construir el makefile para un proyecto Objective-C en el framework de GNUstep es muy sencillo.</p>
<p>Basta con añadir algunas directivas de inclusión de ficheros y la lista de ficheros de código:</p>
<pre class="brush: c">
include $(GNUSTEP_MAKEFILES)/common.make

APP_NAME = edictParser
edictParser_APPLICATION_ICON = icon.png
edictParser_RESOURCE_FILES = icon.png
edictParser_OBJC_FILES = main.m

include $(GNUSTEP_MAKEFILES)/application.make
</pre>
<p>Para el caso de querer utilizar código C++, sustituimos la línea:</p>
<pre class="brush: c">
edictParser_OBJC_FILES = main.m
</pre>
<p>por:</p>
<pre class="brush: c">
edictParser_OBJCC_FILES = main.mm
</pre>
<p>Y un pequeño truco para no tener que modificar el makefile cada vez que añadimos un fichero de código:</p>
<pre class="brush: c">
edictParser_OBJCC_FILES = $(shell ls -c1 *.mm)
</pre>
<p>[Nótese que la extensión para los ficheros Objective-C++ es mm.]</p>


<p>Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-para-obtencion-de-datos-de-cobertura-i/' rel='bookmark' title='Permanent Link: Utilización de gprof/gcov para obtención de datos de cobertura (I)'>Utilización de gprof/gcov para obtención de datos de cobertura (I)</a></li>
<li><a href='http://blog.ilikeblues.com/2008/02/llamadas-a-funciones-estaticas-externas-en-c/' rel='bookmark' title='Permanent Link: Llamadas a funciones estáticas externas en C'>Llamadas a funciones estáticas externas en C</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.ilikeblues.com/2008/12/gnumakefile-para-objective-c-y-objective-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Establecer el &#8220;locale&#8221; para una aplicación C/C++</title>
		<link>http://blog.ilikeblues.com/2008/10/establecer-el-locale-para-una-aplicacion-cc/</link>
		<comments>http://blog.ilikeblues.com/2008/10/establecer-el-locale-para-una-aplicacion-cc/#comments</comments>
		<pubDate>Thu, 09 Oct 2008 09:15:17 +0000</pubDate>
		<dc:creator>ilikeblues</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[locale]]></category>

		<guid isPermaLink="false">http://blog.ilikeblues.com/?p=62</guid>
		<description><![CDATA[A veces puede ser conveniente establecer el &#8220;locale&#8221; de la manera adecuada en una aplicación.
Por ejemplo, si vamos a utilizar expresiones regulares con caracteres no-ASCII (como la ñ o los caracteres acentuados).
Para establecer el locale, podemos utilizar el código:

const char* locstr = setlocale(LC_ALL, &#34;es_ES.UTF8&#34;);

if (locstr == NULL) {
   printf(&#34;SETLOCALE ERROR!\n&#34;);
}

[Consultar API para setlocale.]
Si [...]


Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2008/10/expresiones-regulares-c/' rel='bookmark' title='Permanent Link: Expresiones regulares C'>Expresiones regulares C</a></li>
<li><a href='http://blog.ilikeblues.com/2010/03/aplicacion-offline-para-iphone/' rel='bookmark' title='Permanent Link: Aplicación Offline para iPhone'>Aplicación Offline para iPhone</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>A veces puede ser conveniente establecer el &#8220;locale&#8221; de la manera adecuada en una aplicación.</p>
<p>Por ejemplo, si vamos a utilizar <a href="http://blog.ilikeblues.com/?p=50">expresiones regulares</a> con caracteres no-ASCII (como la ñ o los caracteres acentuados).</p>
<p>Para establecer el locale, podemos utilizar el código:</p>
<pre class="brush: c">
const char* locstr = setlocale(LC_ALL, &quot;es_ES.UTF8&quot;);

if (locstr == NULL) {
   printf(&quot;SETLOCALE ERROR!\n&quot;);
}
</pre>
<p>[Consultar API para <a href="http://linux.die.net/man/3/setlocale">setlocale</a>.]</p>
<p>Si como ejemplo, buscamos la expresión regular &#8220;ñ&#8221; dentro de la cadena &#8220;este año es muy frío&#8221;, obtendremos un resultado diferente, dependiendo del locale definido:</p>
<ol>
<li>Si se ha definido el locale &#8220;es&#8221;:
<pre class="brush: c">
start offset: 6
end offset:  8
</pre>
</li>
<li>Si el locale es, por ejemplo, &#8220;us&#8221;:
<pre class="brush: c">
start offset: 6
end offset:  7
</pre>
</li>
</ol>
<p>Ya conocemos los problemas que presenta C/C++ para tratar caracteres unicode. Pero, al menos, podemos hacer búsquedas y sustituciones de una manera más fiable si el locale definido es el adecuado.</p>


<p>Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2008/10/expresiones-regulares-c/' rel='bookmark' title='Permanent Link: Expresiones regulares C'>Expresiones regulares C</a></li>
<li><a href='http://blog.ilikeblues.com/2010/03/aplicacion-offline-para-iphone/' rel='bookmark' title='Permanent Link: Aplicación Offline para iPhone'>Aplicación Offline para iPhone</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.ilikeblues.com/2008/10/establecer-el-locale-para-una-aplicacion-cc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Expresiones regulares C</title>
		<link>http://blog.ilikeblues.com/2008/10/expresiones-regulares-c/</link>
		<comments>http://blog.ilikeblues.com/2008/10/expresiones-regulares-c/#comments</comments>
		<pubDate>Thu, 09 Oct 2008 08:54:37 +0000</pubDate>
		<dc:creator>ilikeblues</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false">http://blog.ilikeblues.com/?p=50</guid>
		<description><![CDATA[A continuación código de ejemplo que muestra cómo buscar expresiones regulares en cadenas de texto:

regex_t regex;
const int MAXMATCHES = 1;

regmatch_t matches[MAXMATCHES];

const char* str = &#34;Look inside this string...&#34;;
const char* patt = &#34;side&#34;;

size_t size = MAXMATCHES;

int cflags = REG_EXTENDED&#124;REG_ICASE;
int eflags = cflags;

int result = 0;
int rescomp = regcomp(&#38;amp;amp;amp;amp;regex, patt, cflags);
if (rescomp == 0) {
   [...]


Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2008/10/establecer-el-locale-para-una-aplicacion-cc/' rel='bookmark' title='Permanent Link: Establecer el &#8220;locale&#8221; para una aplicación C/C++'>Establecer el &#8220;locale&#8221; para una aplicación C/C++</a></li>
<li><a href='http://blog.ilikeblues.com/2008/02/llamadas-a-funciones-estaticas-externas-en-c/' rel='bookmark' title='Permanent Link: Llamadas a funciones estáticas externas en C'>Llamadas a funciones estáticas externas en C</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>A continuación código de ejemplo que muestra cómo buscar expresiones regulares en cadenas de texto:</p>
<pre class="brush: c">
regex_t regex;
const int MAXMATCHES = 1;

regmatch_t matches[MAXMATCHES];

const char* str = &quot;Look inside this string...&quot;;
const char* patt = &quot;side&quot;;

size_t size = MAXMATCHES;

int cflags = REG_EXTENDED|REG_ICASE;
int eflags = cflags;

int result = 0;
int rescomp = regcomp(&amp;amp;amp;amp;amp;regex, patt, cflags);
if (rescomp == 0) {
   result = regexec((const regex_t*)&amp;amp;amp;amp;amp;regex, str, size, matches, eflags);
}
if (result == REG_NOMATCH) {
   printf(&quot;NOT MATCHED!&quot;);
} else {

   for (int i = 0;i &lt; MAXMATCHES;i++) {
      regoff_t startOff = matches[i].rm_so;
      regoff_t endOff   = matches[i].rm_eo;

      if (startOff != -1) {
         printf(&quot;start offset:  %i&quot;, startOff);
         printf(&quot;end offset:   &quot;%i, endOff);
      }
   }
}
</pre>
<p>Este código imprimirá en el terminal la siguiente salida:</p>
<pre class="brush: c">
start offset: 7
end offset:  11
</pre>
<p>Es decir, delimita el trozo de cadena que &#8220;machea&#8221; la expresión regular.</p>
<p>[En este enlace se puede consultar cómo construir <a href="http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html">expresiones regulares POSIX</a>.]</p>


<p>Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2008/10/establecer-el-locale-para-una-aplicacion-cc/' rel='bookmark' title='Permanent Link: Establecer el &#8220;locale&#8221; para una aplicación C/C++'>Establecer el &#8220;locale&#8221; para una aplicación C/C++</a></li>
<li><a href='http://blog.ilikeblues.com/2008/02/llamadas-a-funciones-estaticas-externas-en-c/' rel='bookmark' title='Permanent Link: Llamadas a funciones estáticas externas en C'>Llamadas a funciones estáticas externas en C</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.ilikeblues.com/2008/10/expresiones-regulares-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Llamadas a funciones estáticas externas en C</title>
		<link>http://blog.ilikeblues.com/2008/02/llamadas-a-funciones-estaticas-externas-en-c/</link>
		<comments>http://blog.ilikeblues.com/2008/02/llamadas-a-funciones-estaticas-externas-en-c/#comments</comments>
		<pubDate>Wed, 27 Feb 2008 11:09:47 +0000</pubDate>
		<dc:creator>ilikeblues</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[How to]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[acceso]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[estático]]></category>
		<category><![CDATA[función]]></category>

		<guid isPermaLink="false">http://blog.ilikeblues.com/?p=25</guid>
		<description><![CDATA[Sí, sí, ya lo sé. ¿Por qué querría alguien hacer una llamada a una función declarada como estática desde otro módulo?
Si una función se ha declarado estática para restringir el acceso a la misma, para no incluirla en el API del módulo, ¿por qué &#8220;bypassear&#8221; la funcionalidad y acceder a ella?
En mi caso, la respuesta [...]


Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2008/10/expresiones-regulares-c/' rel='bookmark' title='Permanent Link: Expresiones regulares C'>Expresiones regulares C</a></li>
<li><a href='http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-para-obtencion-de-datos-de-cobertura-i/' rel='bookmark' title='Permanent Link: Utilización de gprof/gcov para obtención de datos de cobertura (I)'>Utilización de gprof/gcov para obtención de datos de cobertura (I)</a></li>
<li><a href='http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-cobertura-de-ramas-y-ii/' rel='bookmark' title='Permanent Link: Utilización de gprof/gcov: cobertura de ramas (y II)'>Utilización de gprof/gcov: cobertura de ramas (y II)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Sí, sí, ya lo sé. ¿Por qué querría alguien hacer una llamada a una función declarada como estática desde otro módulo?</p>
<p>Si una función se ha declarado estática para restringir el acceso a la misma, para no incluirla en el API del módulo, ¿por qué &#8220;bypassear&#8221; la funcionalidad y acceder a ella?</p>
<p>En mi caso, la respuesta es sencilla: pruebas unitarias. ¿Cómo hacer pruebas unitarias de estas rutinas?</p>
<p>La respuesta es, creando punteros a estas rutinas, accesibles desde otros módulos. Y puesto que cualquier solución implica cambios en los módulos a probar, en el ejemplo a continuación trataré de ser lo menos &#8220;intrusivo&#8221; posible.</p>
<p>Supongamos el módulo stfunc.c:</p>
<pre class="brush: c">
#include &lt;stdio.h&gt;
static int funcprintf(const char* str) {
   return printf(str);
}
</pre>
<p>Para probar esta rutina, tenemos esta otra, en otro fichero diferente (main.c):</p>
<pre class="brush: c">
int main() {
   int a = funcprintf(&quot;Loquesea&quot;);
   return a;
}
</pre>
<p>Si intentamos compilar, obtenemos el error &#8220;undefined reference to `funcprintf&#8217;&#8221;.</p>
<p>Así pues, vamos a crear un puntero a esta rutina para permitir el acceso a la misma desde el módulo de prueba. Creamos un fichero llamado ptrdefs.h:</p>
<pre class="brush: c">
#ifndef _PTRDEFS_H
#define _PTRDEFS_H
int (*fpointer)(const char*) = &amp;funcprintf;
#endif
</pre>
<p>Y modificamos los ficheros anteriores de esta manera:<br />
Fichero stfunc.c:</p>
<pre class="brush: c">
#include &lt;stdio.h&gt;

static int funcprintf(const char* str) {
   return printf(str);
}

#ifdef UNIT_TESTING
#include
&lt;ptrdefs.h&gt;
#endif
</pre>
<p>Fichero main.c:</p>
<pre class="brush: c">
int main() {
   int a = fpointer(&quot;Loquesea&quot;);

   return a;
}
</pre>
<p>Con esto, basta añadir la opción -DUNIT_TESTING para tener acceso a la rutina.</p>
<p>Por tro lado, el fichero ptrdefs.h sólo estará disponible para los tests unitarios. Esto evita el acceso indeseado.</p>
<p>[Código completo del ejemplo: <a href="http://blog.ilikeblues.com/wp-content/uploads/2008/02/static.tgz" title="Código completo del resultado">static.tgz</a>]</p>


<p>Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2008/10/expresiones-regulares-c/' rel='bookmark' title='Permanent Link: Expresiones regulares C'>Expresiones regulares C</a></li>
<li><a href='http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-para-obtencion-de-datos-de-cobertura-i/' rel='bookmark' title='Permanent Link: Utilización de gprof/gcov para obtención de datos de cobertura (I)'>Utilización de gprof/gcov para obtención de datos de cobertura (I)</a></li>
<li><a href='http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-cobertura-de-ramas-y-ii/' rel='bookmark' title='Permanent Link: Utilización de gprof/gcov: cobertura de ramas (y II)'>Utilización de gprof/gcov: cobertura de ramas (y II)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.ilikeblues.com/2008/02/llamadas-a-funciones-estaticas-externas-en-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Utilización de gprof/gcov: cobertura de ramas (y II)</title>
		<link>http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-cobertura-de-ramas-y-ii/</link>
		<comments>http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-cobertura-de-ramas-y-ii/#comments</comments>
		<pubDate>Tue, 05 Feb 2008 08:04:31 +0000</pubDate>
		<dc:creator>ilikeblues</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[How to]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[branch]]></category>
		<category><![CDATA[cobertura]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[gcov]]></category>
		<category><![CDATA[gprof]]></category>
		<category><![CDATA[ramas]]></category>

		<guid isPermaLink="false">http://blog.ilikeblues.com/?p=18</guid>
		<description><![CDATA[Continuando con la temática del post anterior, vamos a ver en este caso, como chequear la cobertura lógica en bloques de código con condiciones de acceso más o menos complejas.
Supongamos el siguiente fichero de código main.c:

En este caso, el script de compilación y ejecución será compexec.sh:

Nótese como la herramienta gcov ha sido ejecutada con las [...]


Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-para-obtencion-de-datos-de-cobertura-i/' rel='bookmark' title='Permanent Link: Utilización de gprof/gcov para obtención de datos de cobertura (I)'>Utilización de gprof/gcov para obtención de datos de cobertura (I)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Continuando con la temática del <a href="http://blog.ilikeblues.com/?p=6" title="Utilización gcov/gprof (I)">post anterior</a>, vamos a ver en este caso, como chequear la cobertura lógica en bloques de código con condiciones de acceso más o menos complejas.</p>
<p>Supongamos el siguiente fichero de código main.c:</p>
<p><a href="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_mainc.png" title="main.c"><img src="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_mainc.png" alt="main.c" /></a></p>
<p>En este caso, el script de compilación y ejecución será compexec.sh:</p>
<p><a href="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_compexecsh.png" title="compexec.sh"><img src="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_compexecsh.png" alt="compexec.sh" /></a></p>
<p>Nótese como la herramienta gcov ha sido ejecutada con las opciones -b y -c. Según &#8220;man gcov&#8221;:</p>
<ol>
<li>-b<br />
&#8211;branch-probabilities<br />
Write branch frequencies to the output file, and write branch summary info to the standard output.  This option allows you to see how often each branch in your program was taken. Unconditional branches will not be shown, unless the -u option is given.</li>
<li>-c<br />
&#8211;branch-counts<br />
Write branch frequencies as the number of branches taken, rather than the percentage of branches taken.</li>
</ol>
<p>Es decir, pedimos a la herramienta que devuelva información sobre ejecución de las &#8220;ramas lógicas&#8221;, dando como resultado el fichero main.c.gcov:</p>
<p><a href="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_bc_output.png" title="main.c.gcov"><img src="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_bc_output.png" alt="main.c.gcov" /></a></p>
<p>Aquí podemos ver información, aunque un tanto críptica, sobre la ejecución de dos bloques if-else. Como puede verse, cada uno de ellos presenta cuatro ramas, numeradas de &#8220;branch 0&#8243; a &#8220;branch 3&#8243;. Veamos a continuación la explicación de estos datos:</p>
<p>Supongamos la condición:</p>
<pre class="brush: c">
if (a || b) {
   x;
} else {
   y;
}
</pre>
<p>Esta condición (o combinación de condiciones) da lugar a 4 ramas, que se corresponden con las posibles combinaciones de valores booleanos de las dos variables:</p>
<p>a  b<br />
&#8212;-<br />
0  0<br />
0  1<br />
1  0<br />
1  1</p>
<p>Podemos reescribir esta condición como:</p>
<pre class="brush: c">
if (a == false) {
   // Branch 0
   if (b == false) {
      // Branch 2
      y;
   } else {
      // Branch 3;
      x;
   }
} else {
   // Branch 1
   x;
}
</pre>
<p>Supongamos ahora la condición:</p>
<pre class="brush: c">
if (a &amp;&amp; b) {
   x;
} else {
   y;
}
</pre>
<p>Como antes, esta condición (o combinación de condiciones) da lugar a 4 ramas, que se corresponden con las posibles combinaciones de valores booleanos de las dos variables:</p>
<p>a  b<br />
&#8212;-<br />
1  1<br />
1  0<br />
0  1<br />
0  0</p>
<p>Podemos reescribir esta condición como:</p>
<pre class="brush: c">
if (a == true) {
   // Branch 0
   if (b == true) {
      // Branch 2
      x;
   } else {
      // Branch 3;
      y;
   }
} else {
   // Branch 1
   y;
}
</pre>
<p>En cualquiera de los casos anteriores, la herramienta gcov (con las opciones -bc) nos devuelve el número de veces que cada una de las ramas nombradas más arriba ha sido ejecutada.</p>
<p>Si se omite la opción -c, los resultados son porcentajes, de manera que la suma de las ejecuciones de todas las ramas deberá ser el 100 %.</p>
<p>Además, se puede deducir que, en cualquiera de los casos:</p>
<p>1.- (nº de ejecuciones de rama 0) + (nº ejecuciones rama 1) = (nº ejecuciones<br />
del if</p>
<p>2.- (nº ejec rama 2) + (nº ejec rama 3) = (nº ejec rama 1)</p>
<p>En conclusión, podemos deducir qué líneas de código y ramas lógicas han sido ejecutadas y añadir/modificar los test cases necesarios para alcanzar la cobertura deseada.</p>
<p>[<a href="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gpc_branch.zip" title="Código completo y resultados">Código completo y resultados.</a>]</p>


<p>Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-para-obtencion-de-datos-de-cobertura-i/' rel='bookmark' title='Permanent Link: Utilización de gprof/gcov para obtención de datos de cobertura (I)'>Utilización de gprof/gcov para obtención de datos de cobertura (I)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-cobertura-de-ramas-y-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Utilización de gprof/gcov para obtención de datos de cobertura (I)</title>
		<link>http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-para-obtencion-de-datos-de-cobertura-i/</link>
		<comments>http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-para-obtencion-de-datos-de-cobertura-i/#comments</comments>
		<pubDate>Mon, 04 Feb 2008 08:28:35 +0000</pubDate>
		<dc:creator>ilikeblues</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[How to]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[cobertura]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[gcov]]></category>
		<category><![CDATA[gprof]]></category>

		<guid isPermaLink="false">http://blog.ilikeblues.com/?p=6</guid>
		<description><![CDATA[Vamos a ver, en unos pasos muy simples, cómo utilizar las herramientas gprof/gcov (integradas con el compilador gcc) para obtener información de cobertura de ejecución de una aplicación. Los resultados son aplicables a cualquier entorno en que dispongamos de estas herramientas (Linux, windows+cygwin, MacOSX+Xcode, etc).
Para empezar el código fuente, main.c:
    
A continuación, [...]


Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-cobertura-de-ramas-y-ii/' rel='bookmark' title='Permanent Link: Utilización de gprof/gcov: cobertura de ramas (y II)'>Utilización de gprof/gcov: cobertura de ramas (y II)</a></li>
<li><a href='http://blog.ilikeblues.com/2009/05/aspectj-aplicado-sobre-una-libreria-jar/' rel='bookmark' title='Permanent Link: AspectJ aplicado sobre una librería jar'>AspectJ aplicado sobre una librería jar</a></li>
<li><a href='http://blog.ilikeblues.com/2010/03/aplicacion-offline-para-iphone/' rel='bookmark' title='Permanent Link: Aplicación Offline para iPhone'>Aplicación Offline para iPhone</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Vamos a ver, en unos pasos muy simples, cómo utilizar las herramientas gprof/gcov (integradas con el compilador gcc) para obtener información de cobertura de ejecución de una aplicación. Los resultados son aplicables a cualquier entorno en que dispongamos de estas herramientas (Linux, windows+cygwin, MacOSX+Xcode, etc).</p>
<p>Para empezar el código fuente, main.c:</p>
<p><a href="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_mainc.png" title="main.c">    </a><a href="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_simple_main.png" title="main.c"><img src="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_simple_main.png" alt="main.c" /></a></p>
<p>A continuación, las instrucciones de compilación y ejecución, compexec.sh:</p>
<p><a href="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_compexec.png" title="compexec.sh"><img src="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_compexec.png" alt="compexec.sh" /></a><a href="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_compexecsh.png" title="compexec.sh"> </a></p>
<p>Como se puede apreciar, son tres las opciones añadidas al compilador/linkador para obtener los resultados esperados:</p>
<ol>
<li>-pgEsto es lo que dice &#8220;man gcc&#8221; acerca de esta opción:
<p>&#8220;<em>Generate extra code to write profile information suitable for the analysis program gprof.  You must use this option when compiling the source files you want data about, and you must also use it when linking.</em>&#8221;</p>
<p>Es decir, prepara el ejecutable para generar información suscpetible de ser utilizada por gprof para obtener información de &#8220;profiling&#8221;. Tras la ejecución de la aplicación generada con esta opción, se crea el fichero gmon.out.</li>
<li>-ftest-coverage</li>
<li>-fprofile-arcsEstas dos opciones son las que indican al compilador que, durante la ejecución de la aplicación, debe generarse información de cobertura.
<p>[La salida "man gcc" para estas opciones es demasiado larga para incluirla aquí, pero puede verse en <a href="http://bama.ua.edu/cgi-bin/man-cgi?gcc" title="man gcc">este enlace</a>.]</p>
<p>El ejecutable compilado/linkado con estas opciones genera los ficheros main.gcno y main.gcda, que contienen los datos utilizados por gcov para generar información &#8220;legible&#8221; de cobertura.</li>
</ol>
<p>Así pues, una vez ejecutada la aplicación y obtenidos estos ficheros, basta con ejecutar el comando gcov:</p>
<p>$ gcov main.c</p>
<p>(tal como se ha incluido en el fichero compexec.sh) y como resultado se obtiene el fichero main.c.gcov:</p>
<p><a href="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_output.png" title="main.c.gcov"><img src="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gcov_output.png" alt="main.c.gcov" /></a></p>
<p>El fichero de resultados muestra el número de veces que un statement ha sido ejecutado.</p>
<p>Las instrucciones marcadas con &#8220;#####&#8221; son aquellas no cubiertas por la ejecución de la aplicación.</p>
<p>[<a href="http://blog.ilikeblues.com/wp-content/uploads/2008/02/gpc.zip" title="Código completo y resultados">Código completo y resultados.</a>]</p>


<p>Relacionados:<ol><li><a href='http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-cobertura-de-ramas-y-ii/' rel='bookmark' title='Permanent Link: Utilización de gprof/gcov: cobertura de ramas (y II)'>Utilización de gprof/gcov: cobertura de ramas (y II)</a></li>
<li><a href='http://blog.ilikeblues.com/2009/05/aspectj-aplicado-sobre-una-libreria-jar/' rel='bookmark' title='Permanent Link: AspectJ aplicado sobre una librería jar'>AspectJ aplicado sobre una librería jar</a></li>
<li><a href='http://blog.ilikeblues.com/2010/03/aplicacion-offline-para-iphone/' rel='bookmark' title='Permanent Link: Aplicación Offline para iPhone'>Aplicación Offline para iPhone</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.ilikeblues.com/2008/02/utilizacion-de-gprofgcov-para-obtencion-de-datos-de-cobertura-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
