<?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>CODARE &#187; Thiago Marcos Santos</title>
	<atom:link href="http://codare.net/author/tmpsantos/feed/" rel="self" type="application/rss+xml" />
	<link>http://codare.net</link>
	<description>Programadores, uni-vos!</description>
	<lastBuildDate>Fri, 03 Dec 2010 21:34:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>C: Escondendo o conteúdo de structs com tipos incompletos</title>
		<link>http://codare.net/2009/08/04/c-escondendo-o-conteudo-de-structs-com-tipos-incompletos/</link>
		<comments>http://codare.net/2009/08/04/c-escondendo-o-conteudo-de-structs-com-tipos-incompletos/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 12:00:36 +0000</pubDate>
		<dc:creator>Thiago Marcos Santos</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[biblioteca]]></category>
		<category><![CDATA[encapsulation]]></category>
		<category><![CDATA[incomplete type]]></category>
		<category><![CDATA[objeto]]></category>
		<category><![CDATA[POO]]></category>
		<category><![CDATA[struct]]></category>

		<guid isPermaLink="false">http://codare.net/?p=476</guid>
		<description><![CDATA[Algumas vezes é possível utilizar alguns paradigmas de orientação à objetos em C. Ao se projetar uma biblioteca, podemos encapsular o conteúdo das structs usando tipos incompletos e provendo funções para manipular o conteúdo destas. Imagine uma biblioteca que cria &#8230; <a href="http://codare.net/2009/08/04/c-escondendo-o-conteudo-de-structs-com-tipos-incompletos/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Algumas vezes é possível utilizar alguns paradigmas de orientação à objetos em C. Ao se projetar uma biblioteca, podemos encapsular o conteúdo das <strong>structs</strong> usando tipos incompletos e provendo funções para manipular o conteúdo destas.</p>
<p>Imagine uma biblioteca que cria um &#8220;objeto&#8221; para representar uma pessoa. Esta biblioteca provê um cabeçalho <strong>person.h</strong> com funções para manipular o &#8220;objeto&#8221;.</p>
<pre>typedef struct person person;

person *person_new(char *name, int age);
void person_free(person *handler);
void person_print(person *handler);</pre>
<p>Note que não existe uma descrição da <strong>struct person</strong> no cabeçalho. A única forma então de manipular esta <strong>struct</strong> é usando as funções, porque os atributos da <strong>struct</strong> não são conhecidos. Esta <strong>struct</strong> portanto caracteriza um tipo incompleto, mas apenas do ponto de vista dos usuários da biblioteca. Em sua implementação, a biblioteca conhece o conteúdo de <strong>person</strong> e consegue manipulá-los, como vemos a seguir.</p>
<pre>#include &lt;string.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

#include "person.h"

struct person {
    char *name;
    int age;
};

person *person_new(char *name, int age)
{
    person *new = malloc(sizeof(*new));

    new-&gt;name = strdup(name);
    new-&gt;age = age;

    return new;
}

void person_free(person *handler)
{
    free(handler-&gt;name);
    free(handler);
}

void person_print(person *handler)
{
    printf("%s - %d\n", handler-&gt;name, handler-&gt;age);
}</pre>
<p>A vantagem de se encapsular os dados, forçando esta política através da técnica apresentada, é que a implementação da biblioteca pode ser alterada sem impacto em seus clientes. <strong>person_new</strong> poderia checar a validade do atributo <strong>age</strong>, retornando um ponteiro nulo caso seja passado uma idade negativa. O código seguinte ilustra um possível cliente da biblioteca, note que não há referência aos atributos de <strong>struct person</strong>.</p>
<pre>#include &lt;person.h&gt;

int main(void)
{
    person *mike = person_new("Mike", 21);

    person_print(mike);
    person_free(mike);

    return 0;
}</pre>
<p>A primeira vez que vi uma biblioteca fazendo uso extenso desta técnica foi no projeto <a href="http://www.opensync.org/">OpenSync</a>, que inspirou este post.</p>
]]></content:encoded>
			<wfw:commentRss>http://codare.net/2009/08/04/c-escondendo-o-conteudo-de-structs-com-tipos-incompletos/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>C/C++: cannot open shared object file</title>
		<link>http://codare.net/2009/07/29/cc-cannot-open-shared-object-file/</link>
		<comments>http://codare.net/2009/07/29/cc-cannot-open-shared-object-file/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 12:00:40 +0000</pubDate>
		<dc:creator>Thiago Marcos Santos</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[CPP]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[-rpath]]></category>
		<category><![CDATA[biblioteca]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[ld]]></category>
		<category><![CDATA[LD_LIBRARY_PATH]]></category>
		<category><![CDATA[linker]]></category>
		<category><![CDATA[shared libraries]]></category>

		<guid isPermaLink="false">http://codare.net/?p=481</guid>
		<description><![CDATA[As bibliotecas compartilhadas são carregadas no início da execução de um programa. No Linux, o dynamic loader procura pelas bibliotecas em /lib e /usr/lib. Caso a biblioteca não esteja presente neste caminho, recebemos uma mensagem de erro parecida com a &#8230; <a href="http://codare.net/2009/07/29/cc-cannot-open-shared-object-file/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As bibliotecas compartilhadas são carregadas no início da execução de um programa. No Linux, o dynamic loader procura pelas bibliotecas em /lib e /usr/lib. Caso a biblioteca não esteja presente neste caminho, recebemos uma mensagem de erro parecida com a mensagem a seguir:</p>
<pre>error while loading shared libraries: libfoo.so:
  cannot open shared object file: No such file or directory</pre>
<p>Imagine um ambiente de desenvolvimento, onde estamos codificando uma biblioteca. Não queremos instalar esta biblioteca no sistema só para testá-la. Uma alternativa é configurar a variável de ambiente LD_LIBRARY_PATH, apontando para o diretório onde se encontra o binário da biblioteca. Assim o dynamic loader vai procurar pela biblioteca também neste diretório.</p>
<pre>$ export LD_LIBRARY_PATH=/home/user/libfoo/</pre>
<p>Uma segunda opção seria no momento em que seu programa é &#8220;linkado&#8221;, passar o caminho da biblioteca para a opção -rpath do linker. Isto coloca o caminho de busca pela biblioteca dentro da estrutura do executável (<a href="http://en.wikipedia.org/wiki/Executable_and_Linkable_Format">ELF</a>). A opção -Wl do gcc serve para passar parâmetros para o linker (usando &#8220;,&#8221; no lugar de espaço) que é chamado automaticamente após a compilação.</p>
<pre>$ gcc -shared -Wall -o libfoo.so foo.c</pre>
<pre>$ gcc -Wall -o test test.c -L/home/user/libfoo/ -lfoo</pre>
<pre>$ ./test <strong># Erro! Não acha a biblioteca libfoo.so</strong></pre>
<pre>$ gcc -Wall -Wl,-rpath,/home/user/libfoo/ -o test test.c \
  -L/home/user/libfoo/ -lfoo</pre>
<pre>$ ./test <strong># Funciona!</strong></pre>
]]></content:encoded>
			<wfw:commentRss>http://codare.net/2009/07/29/cc-cannot-open-shared-object-file/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>C: Múltiplos programas no mesmo binário</title>
		<link>http://codare.net/2009/06/10/c-multiplos-programas-no-mesmo-binario/</link>
		<comments>http://codare.net/2009/06/10/c-multiplos-programas-no-mesmo-binario/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 12:00:06 +0000</pubDate>
		<dc:creator>Thiago Marcos Santos</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[argv]]></category>
		<category><![CDATA[busybox]]></category>
		<category><![CDATA[symlink]]></category>

		<guid isPermaLink="false">http://codare.net/?p=443</guid>
		<description><![CDATA[Um mesmo aplicativo pode se comportar de forma diferente dependendo da forma como é invocado. No exemplo a seguir, o mesmo programa é usado para calcular a raiz quadrada e potência de dois de um dado argumento. #include &#60;libgen.h&#62; #include &#8230; <a href="http://codare.net/2009/06/10/c-multiplos-programas-no-mesmo-binario/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Um mesmo aplicativo pode se comportar de forma diferente dependendo da forma como é invocado. No exemplo a seguir, o mesmo programa é usado para calcular a raiz quadrada e potência de dois de um dado argumento.</p>
<pre>#include &lt;libgen.h&gt;
#include &lt;math.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

int main(int argc, char **argv)
{
    double res;
    char *program = basename(argv[0]);

    if (argc != 2)
        return 1;

    if (!strcmp(program, "sqrt")) {
        res = sqrt(atof(argv[1]));
        printf("%f\n", res);
        return 0;
    }

    if (!strcmp(program, "pow2")) {
        res = pow(atof(argv[1]), 2);
        printf("%f\n", res);
        return 0;
    }

    printf("Invalid program: %s\n", program);

    return 1;
}</pre>
<p>O truque consiste em analisar o primeiro argumento que corresponde ao caminho do binário do programa. No exemplo, decidimos qual ação tomar comparando o nome do programa com &#8220;sqrt&#8221; e &#8220;pow2&#8243;. Para não fazer múltiplas cópias do binário gerado, fazemos links simbólicos.</p>
<pre>$ gcc -Wall -lm -o test test.c
$ ln -s test sqrt
$ ln -s test pow2

$ ./test 5
Invalid program: test

$ ./pow2 5
25.000000

$ ./sqrt 5
2.236068</pre>
<p>A técnica é extensamente utilizada no <a href="http://www.busybox.net/">BusyBox</a> e pode facilmente ser implementada em qualquer outra linguagem de programação.</p>
]]></content:encoded>
			<wfw:commentRss>http://codare.net/2009/06/10/c-multiplos-programas-no-mesmo-binario/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>C, C++: Dupla negação para conversão em booleano</title>
		<link>http://codare.net/2009/06/05/c-cpp-dupla-negacao-para-conversao-em-booleano/</link>
		<comments>http://codare.net/2009/06/05/c-cpp-dupla-negacao-para-conversao-em-booleano/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 12:00:17 +0000</pubDate>
		<dc:creator>Thiago Marcos Santos</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[CPP]]></category>
		<category><![CDATA[!!]]></category>
		<category><![CDATA[bool]]></category>
		<category><![CDATA[booleano]]></category>
		<category><![CDATA[cast]]></category>
		<category><![CDATA[casting]]></category>
		<category><![CDATA[conversao]]></category>
		<category><![CDATA[negation]]></category>

		<guid isPermaLink="false">http://codare.net/?p=410</guid>
		<description><![CDATA[Em C não existe um tipo nativo booleano, temos 0 como falso e tudo diferente de 0 é verdadeiro. Em C++ existe o tipo booleano, onde verdadeiro e falso correspondem respectivamente a 0 e 1. Uma forma de fazer um &#8230; <a href="http://codare.net/2009/06/05/c-cpp-dupla-negacao-para-conversao-em-booleano/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Em C não existe um tipo nativo booleano, temos 0 como falso e tudo diferente de 0 é verdadeiro. Em C++ existe o tipo booleano, onde verdadeiro e falso correspondem respectivamente a 0 e 1.</p>
<p>Uma forma de fazer um &#8220;cast&#8221; em C para um tipo booleano compatível com C++ seria usando a dupla negação, como no exemplo a seguir.</p>
<pre>int value1 = 0;
int value2 = 1;
int value3 = 50;
int value4 = -1;

printf("value1 = %d\n", !!value1); // Imprime value1 = 0
printf("value2 = %d\n", !!value2); // Imprime value2 = 1
printf("value3 = %d\n", !!value3); // Imprime value3 = 1
printf("value4 = %d\n", !!value4); // Imprime value4 = 1</pre>
]]></content:encoded>
			<wfw:commentRss>http://codare.net/2009/06/05/c-cpp-dupla-negacao-para-conversao-em-booleano/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Python: Teste condicional e estruturas de dados vazias</title>
		<link>http://codare.net/2009/06/03/python-teste-condicional-e-estruturas-de-dados-vazias/</link>
		<comments>http://codare.net/2009/06/03/python-teste-condicional-e-estruturas-de-dados-vazias/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 12:00:43 +0000</pubDate>
		<dc:creator>Thiago Marcos Santos</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[if]]></category>
		<category><![CDATA[overload]]></category>
		<category><![CDATA[__len__]]></category>
		<category><![CDATA[__nonzero__]]></category>

		<guid isPermaLink="false">http://codare.net/?p=430</guid>
		<description><![CDATA[Classes que implementam o método __len__, quando testadas com if, este método é invocado. Portanto, para uma lista vazia, o teste falha. x = []; if x: print "OK" # Nao imprime nada Para mudar este comportamento, basta reimplementar o &#8230; <a href="http://codare.net/2009/06/03/python-teste-condicional-e-estruturas-de-dados-vazias/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Classes que implementam o método __len__, quando testadas com if, este método é invocado. Portanto, para uma lista vazia, o teste falha.</p>
<pre>x = [];

if x:
    print "OK" # Nao imprime nada</pre>
<p>Para mudar este comportamento, basta reimplementar o método __nonzero__.</p>
<pre>class MyList(list):
    def __nonzero__(self):
        return True

x = MyList();

if x:
    print "OK" # Imprime OK</pre>
]]></content:encoded>
			<wfw:commentRss>http://codare.net/2009/06/03/python-teste-condicional-e-estruturas-de-dados-vazias/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>C: Descobrir se um processo está em execução</title>
		<link>http://codare.net/2009/05/27/c-descobrir-se-um-processo-esta-em-execucao/</link>
		<comments>http://codare.net/2009/05/27/c-descobrir-se-um-processo-esta-em-execucao/#comments</comments>
		<pubDate>Wed, 27 May 2009 12:00:03 +0000</pubDate>
		<dc:creator>Thiago Marcos Santos</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Shell]]></category>
		<category><![CDATA[daemon]]></category>
		<category><![CDATA[execução]]></category>
		<category><![CDATA[kill]]></category>
		<category><![CDATA[pid]]></category>
		<category><![CDATA[posix]]></category>
		<category><![CDATA[processo]]></category>

		<guid isPermaLink="false">http://codare.net/?p=383</guid>
		<description><![CDATA[No Linux é muito comum um daemon, durante sua execução, criar um arquivo .pid dentro de /var/run. Dentro do arquivo syslogd.pid, por exemplo, contém o PID da instância do syslogd em execução. Usa-se este mecanismo para impedir que duas instâncias &#8230; <a href="http://codare.net/2009/05/27/c-descobrir-se-um-processo-esta-em-execucao/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>No Linux é muito comum um daemon, durante sua execução, criar um arquivo .pid dentro de /var/run. Dentro do arquivo syslogd.pid, por exemplo, contém o PID da instância do syslogd em execução. Usa-se este mecanismo para impedir que duas instâncias do mesmo processo rodem simultaneamente e conflitem na obtenção de recursos.</p>
<p>Porém, a simples existência do arquivo .pid não garante que o processo esteja em execução. Ele pode ter sido fechado de uma forma inesperada e não o apagou. Então, temos que ler o conteúdo do arquivo .pid e certificar que o processo com aquele número de PID está em execução.</p>
<p>A forma mais fácil de fazer isso é enviando o sinal 0 para o processo. O sinal 0 é especial e não é de fato enviado, caso contrário o processo destinatário poderia ser fechado se não tratasse o sinal, mas o retorno da função indica se um sinal real seria enviado com sucesso. O código a seguir exemplifica como aplicar a técnica em C:</p>
<pre>int main(int argc, char **argv)
{
    unsigned int pid;

    if (argc != 2) {
        printf("Uso: %s PID\n", argv[0]);
        return 1;
    }

    pid = (unsigned int) atoi(argv[1]);

    if (!kill(pid, 0))
        printf("%d esta em execucao.\n", pid);
    else
        printf("%d nao esta em execucao.\n", pid);

    return 0;
}</pre>
<p>A mesma técnica pode ser aplicada no terminal:</p>
<pre>$ kill -0 123
$ echo $? # Imprime 0 se o PID 123 existir, 1 caso contrario</pre>
<p>Note que você precisa ter permissão para enviar um sinal para um determinado processo. Para um usuário sem privilégios especiais, a dica só vai funcionar para verificar a existência de processos iniciados pelo próprio usuário.</p>
]]></content:encoded>
			<wfw:commentRss>http://codare.net/2009/05/27/c-descobrir-se-um-processo-esta-em-execucao/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>C, C++: Vetores de tamanho zero</title>
		<link>http://codare.net/2009/05/16/c-cpp-vetores-de-tamanho-zero/</link>
		<comments>http://codare.net/2009/05/16/c-cpp-vetores-de-tamanho-zero/#comments</comments>
		<pubDate>Sat, 16 May 2009 12:00:32 +0000</pubDate>
		<dc:creator>Thiago Marcos Santos</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[CPP]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[gnu]]></category>
		<category><![CDATA[malloc]]></category>
		<category><![CDATA[vetor]]></category>
		<category><![CDATA[zero length]]></category>

		<guid isPermaLink="false">http://codare.net/?p=348</guid>
		<description><![CDATA[Um recurso bastante útil do GCC (apenas) são vetores de tamanho zero. O uso é permitido apenas como último elemento de uma estrutura de dados. struct pessoa { int idade; char nome[0]; }; printf("%d\n", sizeof(struct pessoa)); // Imprime "4" Note &#8230; <a href="http://codare.net/2009/05/16/c-cpp-vetores-de-tamanho-zero/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Um recurso bastante útil do GCC (apenas) são vetores de tamanho zero. O uso é permitido apenas como último elemento de uma estrutura de dados.</p>
<pre>struct pessoa {
    int idade;
    char nome[0];
};</pre>
<pre>printf("%d\n", sizeof(struct pessoa)); // Imprime "4"</pre>
<p>Note que a estrutura tem o mesmo tamanho de um inteiro (na minha máquina). Então podemos concluir que o vetor de tamanho zero não ocupa espaço, ele apenas serve como um identificador para a primeira posição de memória após a estrutura. Isto nos permite fazer algo assim:</p>
<pre>struct pessoa * cria_pessoa(int idade, char* nome)
{
    int tamanho = sizeof(struct pessoa) + strlen(nome) + 1;
    struct pessoa *novo = malloc(tamanho);

    novo-&gt;idade = idade;
    strcpy(novo-&gt;nome, nome);

    return novo;
}</pre>
<pre>int main(void)
{
    struct pessoa *teste = cria_pessoa(18, "Jose");

    /* Imprime "Jose tem 18 anos." */
    printf("%s tem %d anos.\n", teste-&gt;nome, teste-&gt;idade);

    free(teste);

    return 0;
}</pre>
<p>Note que conseguimos alocar toda a memória para a estrutura em apenas uma operação, o que não seria possível caso &#8220;nome&#8221; fosse um ponteiro, o que nos custaria mais uma chamada de malloc. Da mesma forma a desalocação de toda a estrutura foi feita usando um comando.</p>
<p>Esta técnica permite maior flexibilidade e um melhor aproveitamento de memória do que construir a estrutura com o atributo nome sendo &#8220;char nome[200]&#8221; (tamanho fixo) supondo que um nome nunca seria maior que 200 caracteres.</p>
]]></content:encoded>
			<wfw:commentRss>http://codare.net/2009/05/16/c-cpp-vetores-de-tamanho-zero/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>C: Indo para background com o daemon()</title>
		<link>http://codare.net/2009/05/12/c-indo-para-background-com-o-daemon/</link>
		<comments>http://codare.net/2009/05/12/c-indo-para-background-com-o-daemon/#comments</comments>
		<pubDate>Tue, 12 May 2009 12:00:54 +0000</pubDate>
		<dc:creator>Thiago Marcos Santos</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[background]]></category>
		<category><![CDATA[daemon]]></category>
		<category><![CDATA[fork]]></category>
		<category><![CDATA[posix]]></category>
		<category><![CDATA[stdout]]></category>
		<category><![CDATA[terminal]]></category>

		<guid isPermaLink="false">http://codare.net/?p=353</guid>
		<description><![CDATA[A forma tradicional de um programa ir para background é fazendo um fork(), terminar o processo pai e criar uma nova sessão com setsid(). Outra forma mais simples, que de fato encapsula tudo isso e mais um pouco, é apenas &#8230; <a href="http://codare.net/2009/05/12/c-indo-para-background-com-o-daemon/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A forma tradicional de um programa ir para background é fazendo um fork(), terminar o processo pai e criar uma nova sessão com setsid(). Outra forma mais simples, que de fato encapsula tudo isso e mais um pouco, é apenas usar a função daemon, como o Ademar sugeriu <a href="/2007/07/18/c-cpp-fechar-a-saida-padrao-e-de-erro-stdout-stderr/#comment-769">neste</a> comentário.</p>
<pre>#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;

int main(void)
{
    if (daemon(0, 0)) {
        printf("Erro indo para background.\n");
        return 1;
    }

    printf("Esta mensagem nao deve ser impressa.\n");

    sleep(10); // Durma por dez segundos antes de sair

    return 0;
}</pre>
<p>Nada será impresso porque ao passar zero para o segundo parâmetro da função, faz com a saída padrão seja redirecionada para /dev/null, assim como o Cláudio <a href="/2006/10/24/c-redirecionando-stdout/">ensinou</a> (e agora vi que <a href="/2007/07/18/c-cpp-fechar-a-saida-padrao-e-de-erro-stdout-stderr/">dupliquei</a> a dica dele).</p>
<p>Uma vez bem sucedido o comando, nosso processo estará rodando em background desconectado do terminal que o invocou. Você poderá observar que mesmo após o retorno instantâneo do terminal, o nosso programa ainda aparecerá na lista de processos por 10 segundos.</p>
]]></content:encoded>
			<wfw:commentRss>http://codare.net/2009/05/12/c-indo-para-background-com-o-daemon/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>C, C++: Cuidado com funções definidas como macros</title>
		<link>http://codare.net/2009/04/28/c-cpp-cuidado-com-funcoes-definidas-como-macros/</link>
		<comments>http://codare.net/2009/04/28/c-cpp-cuidado-com-funcoes-definidas-como-macros/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 13:10:01 +0000</pubDate>
		<dc:creator>Thiago Marcos Santos</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[CPP]]></category>
		<category><![CDATA[caveats]]></category>
		<category><![CDATA[funções]]></category>
		<category><![CDATA[gotchas]]></category>
		<category><![CDATA[inline]]></category>
		<category><![CDATA[macro]]></category>

		<guid isPermaLink="false">http://codare.net/?p=302</guid>
		<description><![CDATA[Imagine uma função definida em uma macro que faça a potência de dois de um determinado número. Ela poderia ser definida da seguinte forma: #define quadrado(n) \ n * n Acontece que o comportamento, dependendo dos parâmetros, nem sempre é &#8230; <a href="http://codare.net/2009/04/28/c-cpp-cuidado-com-funcoes-definidas-como-macros/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Imagine uma função definida em uma macro que faça a potência de dois de um determinado número. Ela poderia ser definida da seguinte forma:</p>
<pre>#define quadrado(n) \
    n * n</pre>
<p>Acontece que o comportamento, dependendo dos parâmetros, nem sempre é o esperado. Veja o que acontece no exemplo a seguir:</p>
<pre>int main(void)
{
    int a = 2;

    printf("%d\n", quadrado(a)); // Imprime 4

    printf("%d\n", quadrado(a + 1)); // Imprime 5

    return 0;
}</pre>
<p>A expansão da macro quadrado(a + 1), resultou a seguinte expressão:</p>
<pre>a + 1 * a + 1
2 + 1 * 2 + 1 // Substituindo os valores de a
2 + 2 + 1 // Obedecendo a precedência dos operadores
5</pre>
<p>Neste caso, para resolver o problema a sugestão seria usar uma função inline, que assim como a macro, poupa uma chamada de função mas se comporta como uma função convencional.</p>
<pre>inline int quadrado(int n) {
    return n * n;
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://codare.net/2009/04/28/c-cpp-cuidado-com-funcoes-definidas-como-macros/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>C, C++: Usando a seção de dados</title>
		<link>http://codare.net/2009/04/20/c-cpp-usando-a-secao-de-dados/</link>
		<comments>http://codare.net/2009/04/20/c-cpp-usando-a-secao-de-dados/#comments</comments>
		<pubDate>Mon, 20 Apr 2009 12:00:30 +0000</pubDate>
		<dc:creator>Thiago Marcos Santos</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[CPP]]></category>
		<category><![CDATA[char]]></category>
		<category><![CDATA[data section]]></category>
		<category><![CDATA[escopo]]></category>
		<category><![CDATA[execução]]></category>
		<category><![CDATA[memória]]></category>
		<category><![CDATA[pilha]]></category>
		<category><![CDATA[segfault]]></category>

		<guid isPermaLink="false">http://codare.net/?p=295</guid>
		<description><![CDATA[As variáveis da pilha de execução, são automaticamentes desalocadas quando a mesma retorna. No caso do exemplo a seguir, o retorno da função teste() é o endereço de memória da string &#8220;Teste123&#8243; (ou seja, para onde str aponta e não &#8230; <a href="http://codare.net/2009/04/20/c-cpp-usando-a-secao-de-dados/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As variáveis da pilha de execução, são automaticamentes desalocadas quando a mesma retorna. No caso do exemplo a seguir, o retorno da função teste() é o endereço de memória da string &#8220;Teste123&#8243; (ou seja, para onde str aponta e não str propriamente dito).</p>
<pre>char *teste(void)
{
    char *str = "Teste123";

    return str;
}</pre>
<p>Esta string está alocada na seção de dados do programa e existirá durante toda sua execução, não se restringindo ao escopo da pilha, o que torna segura sua utilização.</p>
<p>Vale lembrar que esta string é protegida somente para leitura, qualquer tentativa de escrita em uma de suas posições, fatalmente irá gerar uma falha de segmentação.</p>
]]></content:encoded>
			<wfw:commentRss>http://codare.net/2009/04/20/c-cpp-usando-a-secao-de-dados/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

