<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-3006142001944566780</id><updated>2009-11-03T19:55:44.009-02:00</updated><title type='text'>Tumulto</title><subtitle type='html'>...do cansaço dessa vida, e do peso de ter que ser alguém...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/-/software'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/search/label/software'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>25</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-8150608308716521903</id><published>2009-11-03T19:55:00.002-02:00</published><updated>2009-11-03T19:55:44.016-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Java vs. C#, uma perspectiva estranha</title><content type='html'>Você pode achar o que quiser na disputa entre Java e C#, mas onde na documentação da Microsoft você vai encontrar uma afirmação tão direta, sincera e esclarecedora?&lt;br /&gt;&lt;br /&gt;"Prior to Java 2 Standard Edition, JDK 1.4, the AWT focus subsystem was inadequate."&lt;br /&gt;&lt;br /&gt;http://java.sun.com/javase/6/docs/api/java/awt/doc-files/FocusSpec.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-8150608308716521903?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/8150608308716521903/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=8150608308716521903' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8150608308716521903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8150608308716521903'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/11/java-vs-c-uma-perspectiva-estranha.html' title='Java vs. C#, uma perspectiva estranha'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-4943739368251659661</id><published>2009-10-29T15:13:00.002-02:00</published><updated>2009-10-29T15:13:27.544-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>bug bizarro no RVCT 2.2</title><content type='html'>Descobrimos um bug bizarro no RVCT 2.2 onde a compilação de uma chamada a um operador de conversão do std::auto_ptr gera as seguintes instruções:&lt;br /&gt;&lt;br /&gt;1. push into stack from register&lt;br /&gt;2. unconditionally jump to (1)&lt;br /&gt;&lt;br /&gt;Alguém já viu isso?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-4943739368251659661?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/4943739368251659661/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=4943739368251659661' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4943739368251659661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4943739368251659661'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/10/bug-bizarro-no-rvct-22.html' title='bug bizarro no RVCT 2.2'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-7120115301703993572</id><published>2009-09-18T17:27:00.002-03:00</published><updated>2009-09-18T17:29:56.489-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>C++ e puramente funcional</title><content type='html'>Usando GCC 4.5, Dehydra e um script maroto, seria possível implementar uma verificação estática de que uma função é puramente funcional?&lt;br /&gt;&lt;br /&gt;__attribute__((user("functionally_pure")) int foo_free_of_side_effects (int x, int y);&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-7120115301703993572?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/7120115301703993572/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=7120115301703993572' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7120115301703993572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7120115301703993572'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/09/c-e-puramente-funcional.html' title='C++ e puramente funcional'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-991456882861235300</id><published>2009-09-02T22:44:00.004-03:00</published><updated>2009-09-02T23:35:57.211-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>byte, address e dispositivos</title><content type='html'>Suponha que você tem uma variante de C++0x onde existem apenas os tipos: byte, address e size. byte é uma sequência de oito bits, address é uma posição na memória e size é a distância entre duas posições na memória.&lt;br /&gt;&lt;br /&gt;Com bytes você pode fazer bit shifting e outras operações próprias de sequências de bits; com address você pode navegar pela memória, obtendo sucessores e predecessores; com size você pode navegar pela memória a passos largos.&lt;br /&gt;&lt;br /&gt;Suponha, além disso, que o programa tem à disposição um allocator que obtém pedaços de memória com tamanho fixo, e acesso a dispositivos por uma API razoável.&lt;br /&gt;&lt;br /&gt;Que tipos de programa você poderia escrever?&lt;br /&gt;&lt;br /&gt;Você poderia copiar dados de um dispositivo para outro:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void copy (device&amp; in, device&amp; out)&lt;br /&gt;{&lt;br /&gt;  const size length = allocator.page_size();&lt;br /&gt;  address buffer = allocator.allocate_page();&lt;br /&gt;&lt;br /&gt;  size n;&lt;br /&gt;  while ((n = in.read(buffer, length)) &gt; 0) out.write(buffer, n);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Você poderia copiar dados, criptografando com XOR:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void copy_and_encrypt (device&amp; in, device&amp; out, byte key)&lt;br /&gt;{&lt;br /&gt;  const size length = allocator.page_size();&lt;br /&gt;  address buffer = allocator.allocate_page();&lt;br /&gt;&lt;br /&gt;  size n;&lt;br /&gt;  while ((n = in.read(buffer, length)) &gt; 0)&lt;br /&gt;  {&lt;br /&gt;    for (address i = buffer; i != buffer + length; ++i) *i ^= key;&lt;br /&gt;    out.write(buffer, n);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Acredito que você poderia realizar praticamente todo tipo de criptografia apenas com operações binárias.&lt;br /&gt;&lt;br /&gt;De onde um programa obteria a chave? De outro dispositivo de entrada, talvez.&lt;br /&gt;&lt;br /&gt;Meu ponto é que nada disso está relacionado com aritmética em domínios numéricos; mesmo com a existência de size no programa, que é claramente uma "quantidade". Ainda é possível escrever programas interessantes mesmo sem a possibilidade de realizar aritmética com valores do tipo size.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-991456882861235300?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/991456882861235300/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=991456882861235300' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/991456882861235300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/991456882861235300'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/09/byte-address-e-dispositivos.html' title='byte, address e dispositivos'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-7279776522065663243</id><published>2009-08-31T21:21:00.004-03:00</published><updated>2009-08-31T21:44:25.763-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Dualidade memória/dispositivo</title><content type='html'>Ainda pensando sobre linguagem de programação e sistema, e na possibilidade de se projetar uma API de dispositivos apenas com &lt;span style="font-family:courier new;"&gt;byte&lt;/span&gt; e &lt;span style="font-family:courier new;"&gt;address&lt;&gt;&lt;/span&gt;, me ocorreram os seguintes pensamentos sobre a relação entre os dispositivos e a memória.&lt;br /&gt;&lt;br /&gt;A memória é uma sequência onde ocorrem símbolos, na máquina binária contemporânea esses símbolos são bits e a unidade de armazenagem prática aos programas é o &lt;span style="font-family:courier new;"&gt;byte&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Além disso, na máquina de von Neumann, toda a operação do programa ocorre sobre a memória, inclusive operação sobre dispositivos, que ocorrem ao programa na forma de intervalos especialmente posicionados na memória.&lt;br /&gt;&lt;br /&gt;Programas no sistema Unix, por outro lado, vêem dispositivos na forma de arquivos, com o qual trocam dados; o dispositivo é uma origem de dados e um destino de dados. A API fundamental de dispositivos é &lt;span style="font-family:courier new;"&gt;read&lt;/span&gt; e &lt;span style="font-family:courier new;"&gt;write&lt;/span&gt;. A realização básica de um arquivo é o próprio arquivo de dados, ocorrendo em um sistema de arquivamento.&lt;br /&gt;&lt;br /&gt;É claro que o Unix, aplicando sua filosofia de simplicidade, exibe tudo como arquivo, inclusive todos os dispositivos; programas podem trocar dados com qualquer dispositivo representável em &lt;span style="font-family:courier new;"&gt;/dev&lt;/span&gt;. De fato, existe &lt;span style="font-family:courier new;"&gt;/dev/mem&lt;/span&gt; que reflete como um dispositivo a própria memória.&lt;br /&gt;&lt;br /&gt;Por fim, borrando a distinção entre o que o processo de usuário vê e o que o sistema vê, existem os mecanismo de mapeamento em memória, que representam dispositivos (entre outras coisas) como intervalos de memória ao processo.&lt;br /&gt;&lt;br /&gt;É fácil observar que a memória, fisicamente, e o dispositivo, abstratamente, são elementos e conceitos que se substituem e se sobrepõe. A noção de &lt;span style="font-style: italic;"&gt;character device&lt;/span&gt; no Unix parece nascer exatamente daqueles dispositivos cuja natureza é a de um intervalo de átomos, um conceito cuja necessidade surge após a decisão de representar tudo como arquivos.&lt;br /&gt;&lt;br /&gt;A união de memória virtual e o aspecto memória de um dispositivo ocorre no mecanismo de mapeamento em memória; no projeto de uma API de I/O assíncrono, a necessidade de expor páginas da memória de um processo ao &lt;span style="font-style: italic;"&gt;driver&lt;/span&gt; do dispositivo para DMA também ocorre.&lt;br /&gt;&lt;br /&gt;Programas sintonizados à API de arquivos frequentemente desejam comunicar a subprogramas dados em memória, e então a necessidade de um pseudo-dispositivo cuja representação é memória surge.&lt;br /&gt;&lt;br /&gt;Tudo isso implica que o projeto de uma API de dispositivos é o projeto de uma API de memória, e todo projeto de um &lt;span style="font-style: italic;"&gt;abstract data type&lt;/span&gt; dispositivo implica o projeto de um &lt;span style="font-style: italic;"&gt;abstract data type&lt;/span&gt; intervalo-de-memória.&lt;br /&gt;&lt;br /&gt;Que um aspecto ofereça melhor desempenho a um programa é função das necessidades desse programa. Programas que lêem arquivos frequentemente mapeiam este arquivo na memória e o lêem como um intervalo de memória. Programas que computam na memória o &lt;span style="font-style: italic;"&gt;digest&lt;/span&gt; SHA-1 de uma informação frequentemente operam um pseudo-dispositivo onde escrevem blocos fixos de dados iterativamente.&lt;br /&gt;&lt;br /&gt;Fundamentalmente, eis a questão: um dispositivo deve ser convertível para um intervalo-de-memória e vice-versa. O desafio é projetar tal API segundo todos os critérios de boas práticas realisticamente em um sistema.&lt;br /&gt;&lt;br /&gt;Mudando de assunto, eis o projeto 9.1 do &lt;span style="font-style: italic;"&gt;Elements of Programming&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;"Modern computing systems include highly optimized library procedures for copying memory; for example, memmove and memcpy, which use optimization techniques not discussed in this book. Study the procedures provided on your platform, determine the techniques they use (for example, loop unrolling and software pipelining), and design abstract procedures expressing as many of these techniques as possible. What type requirements and preconditions are necessary for each technique? What language extensions would allow a compiler full flexibility to carry out these optimizations?"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-7279776522065663243?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/7279776522065663243/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=7279776522065663243' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7279776522065663243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7279776522065663243'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/08/dualidade-memoriadispositivo.html' title='Dualidade memória/dispositivo'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-4788212197291742917</id><published>2009-08-25T21:30:00.002-03:00</published><updated>2009-08-25T23:00:31.916-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Máquina de Turing</title><content type='html'>Acho que atingi uma compreensão de como uma máquina de computação contemporânea cumpre os requisitos restritos da máquina universal de computação.&lt;br /&gt;&lt;br /&gt;A máquina universal de computação é uma máquina que opera sobre símbolos ocorrendo um espaço unidimensional infinito. A máquina transforma seu estado de acordo com o símbolo atual; ela pode, por exemplo, avançar ou retroceder no espaço de símbolos, reescrever o símbolo em uma determinada posição, ou qualquer outra coisa.&lt;br /&gt;&lt;br /&gt;A máquina se torna útil com a especificação do conjunto de símbolos representáveis e do significado de todos esses símbolos. Assim, um símbolo pode significar "avance três posições" e outro símbolo pode significa "substitua o próximo símbolo com o símbolo seguinte a esse, e vice-versa.&lt;br /&gt;&lt;br /&gt;É claro que nenhuma máquina concreta terá acesso a um espaço infinito para símbolos; portanto, podemos falar sobre uma máquina universal restrita com espaço finito para símbolos.&lt;br /&gt;&lt;br /&gt;Uma máquina universal binária é uma máquina cujos símbolos são 0 e 1. Uma tal máquina não pode significar muita coisa com apenas um símbolo, mas nada impede que significados especiais sejam atribuídos a sequências específicas de símbolos.&lt;br /&gt;&lt;br /&gt;Assim, podemos falar sobre símbolos complexos, compostos por uma sequência de símbolos, que na máquina binária será uma sequência de 0s e 1s. A máquina binária possui portanto uma regra implícita: enquanto um símbolo complexo não for compreendido, ela avança para o próximo símbolo.&lt;br /&gt;&lt;br /&gt;Quando um símbolo completo é compreendido, a máquina realiza a transformação especificada para aquele símbolo complexo.&lt;br /&gt;&lt;br /&gt;É claro que, em uma máquina concreta, o número de símbolos complexos especificáveis é finito, já que os próprios símbolos complexos devem ser sequências finitas de símbolos fundamentais, e portanto existe uma combinação finita de tais símbolos complexos.&lt;br /&gt;&lt;br /&gt;Mas um conjunto suficientemente grande pode representar todas as operações possíveis sobre uma memória sequencial de símbolos fundamentais, como: se o valor lógico do próximo símbolo complexo for verdade avance para a posição determinada pelo símbolo complexo seguinte a este, senão pelo símbolo complexo duas posições depois.&lt;br /&gt;&lt;br /&gt;Isso é verdade porque, se podemos computar matemática fundamental, podemos computar qualquer coisa.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-4788212197291742917?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/4788212197291742917/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=4788212197291742917' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4788212197291742917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4788212197291742917'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/08/maquina-de-turing.html' title='Máquina de Turing'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-9125880897422327369</id><published>2009-08-21T14:10:00.003-03:00</published><updated>2009-08-21T15:27:27.137-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Tipos de dados primitivos 2</title><content type='html'>Em C++, existe uma certa ambiguidade no significado dos tipos primitivos.&lt;br /&gt;&lt;br /&gt;Tome char, por exemplo. char pode ser apenas char, pode ser signed char ou pode ser unsigned char. Mas char deve ser caractere, certo? Qual é o significado de um caractere ser signed ou unsigned? Nenhuma.&lt;br /&gt;&lt;br /&gt;Existe, é claro, uma razão porque é possível especificar unsigned ou signed char; porque char é um valor inteiro de tamanho 1. De certa forma, char é o menor de todos os int, e foi projetado para ser usado como tal. Em uma máquina convencional, char é um inteiro de 8 bits. C99 na prática exige que char ocupe 8 bits.&lt;br /&gt;&lt;br /&gt;Em C original, o ponteiro para char possuía a propriedade adicional de representar qualquer endereço válido de memória. Portanto, uma função que lê dados de um dispositivo qualquer para a memória aceitaria um parâmetro do tipo ponteiro para char significando o endereço de memória de um buffer.&lt;br /&gt;&lt;br /&gt;É claro que isso provoca uma confusão com outro sigficado de ponteiro para char, a string de bytes terminada por NULL, ou NTBS. Por esse motivo, alguns programas e bibliotecas usam ponteiro para unsigned char para representar segmentos opacos de memória, como buffers de I/O.&lt;br /&gt;&lt;br /&gt;Em C99, qualquer ponteiro é conversível para um ponteiro para algum char. Em C++ isso não é permitido. Em ambas as linguagens, qualquer ponteiro é conversível para um ponteiro para void.&lt;br /&gt;&lt;br /&gt;Aritmética de ponteiro não é permitia para um ponteiro para void, infelizmente; programas que desejam atravessar a memória por qualquer razão devem usar ponteiros para char. Isso exige o uso de conversões por reinterpretação, como a notação de cast com parênteses, ou reinterpret_cast.&lt;br /&gt;&lt;br /&gt;Existem aqui diversas necessidades diferentes. Uma delas é endereçar memória opaca, sem interpretação, e endereçá-la completamente. Outra é representar o menor valor inteiro possível na plataforma. Outra é representar um caractere. Outra é representar um segmento de texto.&lt;br /&gt;&lt;br /&gt;Representar um caractere como o menor inteiro da plataforma é, hoje sabemos, uma ingenuidade, e existem diversas representações de caracteres que usam um número variado dessas unidades para caracteres, ou usam um número fixo de duas ou mais dessas unidades.&lt;br /&gt;&lt;br /&gt;Assim, quando ocorre em um programa um caractere literalmente, como &lt;span style="font-style: italic;"&gt;f&lt;/span&gt;, qual é a quantidade de armazenagem que o valor correspondente ocupa na memória? Depende da representação de caracteres usada no sistema alvo -- e naturalmente na unidade de memória da arquitetura alvo.&lt;br /&gt;&lt;br /&gt;Eu não gosto dessa notação de signed e unsigned. Parece ter havido um problema original em que os ints tiveram de ser subitamente diferenciados entre inteiros e inteiros positivos. Não entendo como isso pode ter sido súbito, mas ainda não conheço bem a história da computação para saber como eram as máquinas quando C foi projetada. Me parece apenas que é um sistema de tipos obsoleto. As máquinas conhecem os naturais, ou inteiros positivos, representados em base 2 e conhece os inteiros representados em base 2 com complemento de dois.&lt;br /&gt;&lt;br /&gt;Caracteres são um outro tipo de informação, distinto de números, apesar de logicamente relacionáveis -- a representação de um caractere é um índice em uma tabela.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-9125880897422327369?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/9125880897422327369/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=9125880897422327369' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/9125880897422327369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/9125880897422327369'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/08/tipos-de-dados-primitivos-2.html' title='Tipos de dados primitivos 2'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-1888911903431537837</id><published>2009-08-18T11:06:00.002-03:00</published><updated>2009-08-18T12:03:29.070-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Declarações, nomes e objetos</title><content type='html'>Uma linguagem como C++ é chamada declarativa porque o elemento central de sua sintaxe é a declaração.&lt;br /&gt;&lt;br /&gt;Uma declaração é uma construção sintática que associa um nome a um sujeito -- ou um identificador e um objeto. O caso simples é a declaração de uma variável.&lt;br /&gt;&lt;br /&gt;Creio que um objeto é um ente totalmente abstrato do discurso, ao contrário do que a literatura sugere. Certamente podemos falar sobre o objeto e descrever suas propriedades; mas na máquina concreta, o significado de um objeto transita entre seus três aspectos fundamentais: seu valor, sua armazenagem e sua localização.&lt;br /&gt;&lt;br /&gt;O tipo de um objeto, por princípio, corresponde ao domínio de seus valores. Assim, podemos considerar os dois tipos primitivos fundamentais que sugeri anteriormente, byte e address&lt;t&gt;. byte é um pseudo-tipo para "o que quer que seja, armazenável na memória". address&lt;t&gt; é o tipo do valor "localização na memória de um valor do tipo T". address&lt;byte&gt; é o tipo do valor "localização na memória do que quer que seja".&lt;br /&gt;&lt;br /&gt;Em C++, a função de "o que quer que seja" é cumprida por char; char é a unidade de memória na máquina abstrata C++. A função de "localização na memória do que quer que seja" é cumprida em parte por void*, para o qual podemos converter qualquer T*, e em parte por char*, que garantidamente pode endereçar qualquer localização válida na memória.&lt;br /&gt;&lt;br /&gt;Valores do tipo byte são apenas copiáveis; é possível, no mínimo, reproduzir o padrão de bits de uma armazenagem para a outra.&lt;br /&gt;Valores do tipo address&lt;t&gt; são copiáveis; além disso, o domínio de address&lt;t&gt; é equivalente ao domínio dos naturais, e suporta a mesma aritmética; por fim, existe a operação de-referência, que transforma um valor address&lt;t&gt; em um valor T.&lt;br /&gt;&lt;br /&gt;Com esses dois tipos podemos fazer muito pouco, mas podemos fazer algo; é possível escrever um programa capaz de copiar dados de um dispositivo para o outro apenas com byte e address&lt;t&gt;. Seria também possível escrever programas capazes de rearranjos e outras operações similares.&lt;br /&gt;&lt;br /&gt;Esses programas não poderiam ser muito sofisticados porque os únicos julgamentos possíveis seriam sobre localizações de objetos, e não seus valores. Seria possível, por exemplo, escrever um programa que inverte uma sequência de bytes, etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-1888911903431537837?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/1888911903431537837/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=1888911903431537837' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/1888911903431537837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/1888911903431537837'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/08/declaracoes-nomes-e-objetos.html' title='Declarações, nomes e objetos'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-6260156903107536611</id><published>2009-08-17T14:12:00.003-03:00</published><updated>2009-08-17T14:44:29.531-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Tipos de dados primitivos</title><content type='html'>Após uma longa considerção sobre o assunto, e bastante tempo livre durante as férias, cheguei a uma opinião sobre que conjunto de tipos de dados primitivos eu gostaria de ver em Pedro C++.&lt;br /&gt;&lt;br /&gt;A idéia de que há signed e unsigned como qualificadores distintos do tipo de dados não me parece muito coerente; um signed integer e um unsigned integer são valores em domínios completamente distintos. De fato, um unsigned integer é um natural, e foi essa intuição que me levou eventualmente a compilar a seguinte lista:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;byte&lt;/li&gt;&lt;li&gt;address&lt;/li&gt;&lt;li&gt;natural&lt;/li&gt;&lt;li&gt;integer&lt;/li&gt;&lt;li&gt;rational&lt;/li&gt;&lt;li&gt;real&lt;/li&gt;&lt;li&gt;complex&lt;/li&gt;&lt;/ul&gt;Com os tipos primitivos byte a address seria possível escrever um sistema capaz de transportar dados entre dispositivos. Um tal sistema, ou sub-sistema, não tem interesse na representação de um dado; isso percebe-se claramente nas APIs de I/O do Unix, cujo tipo de dado é void*. Este tipo, em Pedro C++, seria um address&lt;byte&gt;.&lt;br /&gt;&lt;br /&gt;Para a computação matemática pura temos a seleção completa de domínios algébricos. natural, integer e real são verdadeiramente primitivos, enquanto rational e complex são derivados destes. Em uma máquina convencional, natural é representado diretamente em base 2, integer é representado em base 2 por complemento de dois, e real é representado na forma dada em IEEE 754. Uma linguagem rica permitira que esses tipos sejam genéricos no tamanho; natural&lt;16&gt; é um natural ocupando dois bytes, integer&lt;64&gt; é um inteiro ocupando 8 bytes.&lt;br /&gt;&lt;br /&gt;Deve ser possível, com base em natural, implementar qualquer domínio homomórfico com os naturais, como por exemplo caracteres em um mapa de caracteres.&lt;br /&gt;&lt;br /&gt;É claro que nada disso é remotamente suficiente para uma linguagem na prática; é preciso ainda falar sobre muitas coisas muito simples, como a representação e o tipo de valores representados literalmente no programa etc.&lt;br /&gt;&lt;br /&gt;NOTA: não tenho certeza se "homomórfico" foi a palavra certa ali em cima.&lt;br /&gt;&lt;/byte&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-6260156903107536611?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/6260156903107536611/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=6260156903107536611' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6260156903107536611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6260156903107536611'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/08/tipos-de-dados-primitivos.html' title='Tipos de dados primitivos'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-4101376501650419301</id><published>2009-08-11T10:58:00.003-03:00</published><updated>2009-08-11T11:01:09.053-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'></title><content type='html'>Por que eu desejo escrever explicitamente sobre o ambiente de programação C++?&lt;br /&gt;Por que existem documentos com frases assim:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;To compile your programs, link with the C++CSP2 library. On GCC this can be achieved by using the "-lcppcsp2" option on the command-line.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Se eu tentar compilar o programa de exemplo deste documento seguindo essas instruções à risca ocorerrá o seguinte:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;/usr/bin/ld: cannot find -lcppcsp2&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;collect2: ld returned 1 exit status&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Por quê? Por que você não pode ingenuamente dizer quais bibliotecas você quer; o ambiente de ligação de programas com bibliotecas envolve a localização da biblioteca. Onde ela está?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-4101376501650419301?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/4101376501650419301/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=4101376501650419301' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4101376501650419301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4101376501650419301'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/08/por-que-eu-desejo-escrever.html' title=''/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-2140712304034009268</id><published>2009-08-08T13:55:00.003-03:00</published><updated>2009-08-08T13:59:22.892-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Novo projeto: monografia sobre o ambiente de programação C++</title><content type='html'>Como algumas pessoas sabem, um dos meus objetivos de mais longo prazo é projetar um sistema operacional em C++ e aplicar nesse projeto os métodos da orientação ao objetos, da programação genérica e da programação funcional.&lt;br /&gt;&lt;br /&gt;Seria, é claro, ingênuo simplesmente acreditar que essa atividade é como programar uma variante do Unix convencional, meramente usando o compilador C++. A linguagem impõe requisitos muito mais interessantes sobre a ABI do sistema que C, uma linguagem simplória nesse sentido.&lt;br /&gt;&lt;br /&gt;Assim sendo, comecei a estudar a questão da ABI do sistema e como C++ lida com ela, bem como o suporte ao mecanismo central da programação genérica em C++, os templates.&lt;br /&gt;&lt;br /&gt;Tudo isso me sugeriu este novo projeto: escrever uma monografia sobre o ambiente completo de programação em C++, evidenciando detalhes ocultos ao programador, como a atuação do linker, do assembler, do compilador, do loader e mesmo de drivers de compilação como o make.&lt;br /&gt;&lt;br /&gt;Quem sabe esse não será meu primeiro livro publicado?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-2140712304034009268?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/2140712304034009268/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=2140712304034009268' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/2140712304034009268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/2140712304034009268'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/08/novo-projeto-monografia-sobre-o.html' title='Novo projeto: monografia sobre o ambiente de programação C++'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-8506715997943287898</id><published>2009-08-01T00:47:00.001-03:00</published><updated>2009-08-01T00:47:48.224-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Sigyn: componentes genéricos para networking</title><content type='html'>Gostaria de anunciar o lançamento da biblioteca Sigyn.&lt;br /&gt;&lt;br /&gt;A Sigyn contém diversos componentes genéricos para o desenvolvimento&lt;br /&gt;de servidores de rede concorrentes. Ela também contém exemplos para&lt;br /&gt;protocolos básicos como chargen e discard.&lt;br /&gt;&lt;br /&gt;O código-fonte da biblioreca está disponível neste repositório&lt;br /&gt;Subversion:&lt;br /&gt;&lt;br /&gt;  http://ccppbrasil.googlecode.com/svn/users/pedro.lamarao/sigyn&lt;br /&gt;&lt;br /&gt;Documentação sobre a biblioteca está disponível aqui:&lt;br /&gt;&lt;br /&gt;  http://code.google.com/p/ccppbrasil/wiki/Sigyn&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-8506715997943287898?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/8506715997943287898/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=8506715997943287898' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8506715997943287898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8506715997943287898'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/08/sigyn-componentes-genericos-para.html' title='Sigyn: componentes genéricos para networking'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-8396200423735890975</id><published>2009-07-28T13:01:00.002-03:00</published><updated>2009-07-28T13:52:05.132-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Pesquisando Sistemas Operacionais</title><content type='html'>O iniciante em qualquer nova área de conhecimento sofre muito, na minha experiência, com as exigências transversais ao puro conhecimento que se impõe a ele.&lt;br /&gt;&lt;br /&gt;O programador iniciante, por exemplo, sofre com a ferramenta de compilação, com o ambiente de compilação, com as peculiaridades do linker e do loader no sistema que ele está usando.&lt;br /&gt;&lt;br /&gt;Da mesma forma, quem deseja iniciar uma pesquisa em sistemas operacionais deve lidar com problemas transversais aos algortimos de escalonamento e gerência de memória, como a singela atividade de bootar o kernel.&lt;br /&gt;&lt;br /&gt;Reencontrei hoje uma ferramenta que me auxiliou muito nas minhas primeiras tentativas: o GRUB. Essa ferramenta não só facilita o processo de boot, resolvendo os problemas iniciais, como oferece ao kernel um protocolo de início muito similar ao protocolo de início da própria linguagem de programação, com uma função main.&lt;br /&gt;&lt;br /&gt;O projeto GRUB vai além e oferece código-fonte em assembler e C para um kernel capaz de imprimir "Hello World!" de modo que qualquer programador minimamente determinado poderá iniciar seus estudos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-8396200423735890975?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/8396200423735890975/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=8396200423735890975' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8396200423735890975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8396200423735890975'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/07/pesquisando-sistemas-operacionais.html' title='Pesquisando Sistemas Operacionais'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-1082279253215522105</id><published>2009-02-28T16:38:00.003-03:00</published><updated>2009-02-28T17:04:06.054-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>POSIX/C++</title><content type='html'>No final de 2007, o IEEE aprovou a criação do projeto "POSIX-C++ Binding", com o propósito de aumentar a portabilidade de programas C++ que façam uso das interfaces de sistema especificadas em POSIX.&lt;br /&gt;&lt;br /&gt;Este grupo de trabalho foi "fretado" inicialmente para entregar seu produto em Dezembro de 2011.&lt;br /&gt;&lt;br /&gt;Discussões ocorrem em uma &lt;a href="https://www.redhat.com/mailman/listinfo/posix-c++-wg"&gt;lista de discussão&lt;/a&gt; pública.&lt;br /&gt;&lt;br /&gt;Os trabalhos iniciais envolveram a adequação da nova biblioteca de &lt;span style="font-style: italic;"&gt;threads&lt;/span&gt;, componente da biblioteca padrão do C++0x, e especificar sua implementação sobre as interfaces de sistema especificadas em POSIX.&lt;br /&gt;&lt;br /&gt;Dois outros projetos estão atualmente em discussão: &lt;span style="font-style: italic;"&gt;bindings&lt;/span&gt; C++ para as interfaces de sockets, e &lt;span style="font-style:italic;"&gt;bindings&lt;/span&gt; C++ para as interfaces do ligador dinâmico.&lt;br /&gt;&lt;br /&gt;Eu estou trabalhando no projeto de bindings C++ para as interfaces de sockets; mais informações podem ser obtidas &lt;a href="http://code.google.com/p/ccppbrasil/wiki/POSIX_CXX"&gt;aqui&lt;/a&gt;. Meu trabalho está acontecendo sob a bandeira do &lt;a href="http://www.ccppbrasil.org/"&gt;Grupo de Usuários de C e C++ do Brasil&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Na próxima reunião do grupo de trabalho, dia 07 de Março, esses dois projetos serão tema da pauta de discussão. Infelizmente eu ainda não obtive um visto para participar dessa reunião; com sorte isso será possível.&lt;br /&gt;&lt;br /&gt;O objetivo da &lt;span style="font-style:italic;"&gt;binding&lt;/span&gt; para as interfaces de socket é basicamente produzir uma classe que aplique as técnicas de gerência de recurso em C++ no projeto de uma classe que represente um socket. Outros objetivos são melhorar a utilização das estruturas de dados representativas de endereços de socket, o uso de atributos de socket e das interfaces de tradução de nomes.&lt;br /&gt;&lt;br /&gt;Ao longo deste processo se tornou claro que seria útil acrescentar às estruturas de dados simples especificadas em POSIX elementos como construtores e sobrecargas de operadores, para tornar mais simples e mais eficiente a inicialização de objetos destes tipos e sua operação.&lt;br /&gt;&lt;br /&gt;Estou prestes a publicar agora meus primeiros trabalhos nesse sentido, na forma de uma modificação da GNU libc, usável com o GCC 4.4. Informações estão na &lt;a href="http://code.google.com/p/ccppbrasil/wiki/POSIX_CXX"&gt;mesma página&lt;/a&gt; mencionada acima.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-1082279253215522105?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/1082279253215522105/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=1082279253215522105' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/1082279253215522105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/1082279253215522105'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/02/posixc.html' title='POSIX/C++'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-1424165641738543851</id><published>2008-05-08T14:57:00.006-03:00</published><updated>2008-05-08T15:27:55.648-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Projeto Orientado a Componentes, parte IV</title><content type='html'>Uma ligeira digressão, para aproveitar a oportunidade que se apresenta; apresentei esta semana um brevíssimo seminário sobre interoperabilidade entre C++ e Java (com ênfase na ferramenta SWIG).&lt;br /&gt;&lt;br /&gt;O problema a resolver, quando a necessidade de interoperabilidade entre C++ e a Java surge, é exatamente um problema de projeto de componente, por uma via indireta: se não é tão necessária a garantia de substituição de componentes, é inescapável a completa separação entre a implementação do "componente C++" e do "componente Java" devido ao completo isolamento entre seus espaços de memória.&lt;br /&gt;&lt;br /&gt;Esta mesma situação ocorre em um sistema convencional de componentes em que cada componente se localiza em processos distintos, ou mesmo em sistemas distintos, se comunicando através de algum mecanismo inter-processos. O próximo passo na escala evolutiva do projeto de sistemas, o projeto orientado a serviços, lida explicitamente com esta situação, já que se assume como normal que serviços se localizam em sistemas (portanto processos) distintos.&lt;br /&gt;&lt;br /&gt;Esse contexto, e as restrições que ele impõe, transforma a natureza da troca de informação; a memória de um processo não é mais um recurso compartilhado entre rotinas.&lt;br /&gt;&lt;br /&gt;Considere a seguinte função em C, parte de uma interface de componente IFoo. (O componente concreto Foo implementa a interface IFoo.)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  Foo*&lt;br /&gt;  foo_retrieve_from_persistence (char* foo_name);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Esta função recebe uma NTBS identificando unicamente um objeto Foo na persistência e retorna o endereço do objeto Foo na memória, trazendo o objeto para a memória uma primeira vez se necessário.&lt;br /&gt;&lt;br /&gt;Suponha que seja desejável, através de um programa Java, usar objetos Foo obtidos através desta função.&lt;br /&gt;&lt;br /&gt;Do componente Bar, uma operação obtém uma referência a uma implementação de IFoo e decide chamar a operação foo_retrieve_from_persistence, passando como argumento uma NTBS. Observe que uma NTBS é uma referência a um espaço contíguo de memória; simplesmente entregar esse endereço para o componente Foo causará um desastre quando este componente resolver acessar esse endereço em seu próprio espaço de memória, cujo significado é incerto. Do mesmo problema sofre o valor de retorno da função; este é o endereço de um objeto na memória do componente Foo, cujo significado no espaço da memória de Bar é incerto.&lt;br /&gt;&lt;br /&gt;Essa situação exibe a impossibilidade de tratar a semântica de referência, na travessia do limiar entre componentes, da mesma maneira como é tratada em projetos mais simples. Como já dissemos, não é possível assumir a memória como recurso compartilhado entre operações em um projeto orientado a componentes. [1]&lt;br /&gt;&lt;br /&gt;A solução canônica é copiar esses valores. Esta tarefa deve ser realizado por aquele elemento do sistema que existe no umbral entre componentes e é responsável por transportar informação de um lado para o outro. Este elemento deverá, então, copiar todo o segmento de memória endereçado por foo_name da memória do componente Bar para a memória do componente Foo. Esta atividade se denomina "data marshalling" em um certo vocabulário e regras particulares de "data marshalling" são chamadas "type maps" em um certo outro vocabulário.&lt;br /&gt;&lt;br /&gt;Este é um exemplo simples de "type map" que transporta um objeto String do Java para um argumento de tipo const std::string&amp;amp; do C++.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  // na prática, estes objetos são argumentos de uma função JNI.&lt;br /&gt;  extern JNIEnv* jenv;&lt;br /&gt;  extern jstring jargN;&lt;br /&gt;&lt;br /&gt;  // type map&lt;br /&gt;  const char *argN_pstr = (const char *)jenv-&gt;GetStringUTFChars(jargN, 0);&lt;br /&gt;  if (!argN_pstr) return 0;&lt;br /&gt;  std::string argN_str(argN_pstr);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A função GetStringUTFChars realiza a tarefa concreta de copiar os segmentos de memória do espaço de memória Java para o espaço de memória C++. Assim, a operação da interface de componente Java/JNI terá a seguinte forma:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  public static native jlong foo_retrieve_from_persistence (String foo_name);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Essa solução, infelizmente, não resolverá o problema do valor de retorno da função. Foo não é um tipo primitivo da linguagem; não existe uma função na JNI para copiar objetos Foo. Mesmo que existisse, Foo é um objeto; o que nós queremos fazer com ele é chamar suas operações. De certa forma, nossa vontade se divide em duas: expor ao programa Java as operações da classe Foo e expor ao programa Java objetos Foo sobre o qual operar. Essas duas necessidades serão resolvidas com mecanismos diferentes.&lt;br /&gt;&lt;br /&gt;Digamos que esta seja a classe Foo.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Foo {&lt;br /&gt;public:&lt;br /&gt;&lt;br /&gt;    Foo (char* name);&lt;br /&gt;&lt;br /&gt;    char*&lt;br /&gt;    ask_question (char* question);&lt;br /&gt;&lt;br /&gt;    char*&lt;br /&gt;    get_name () const;&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A primeira vontade é realizável produzindo, para cada operação de Foo, uma operação na interface do componente IFoo.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    Foo*&lt;br /&gt;    Foo_new (char* name);&lt;br /&gt;&lt;br /&gt;    void&lt;br /&gt;    Foo_delete (Foo* foo);&lt;br /&gt;&lt;br /&gt;    char*&lt;br /&gt;    Foo_ask_question (Foo* foo, char* question);&lt;br /&gt;&lt;br /&gt;    char*&lt;br /&gt;    Foo_get_name (const Foo* foo);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A segunda é entregando ao programa Java o endereço do objeto Foo necessário. Chegamos, aparentemente, a um impasse; já que nosso problema original era justamente como transportar o valor de retorno da função foo_retrieve_from_persistence, que é do tipo Foo*! Porém, tendo caminhado até aqui, o problema se torna ligeiramente diferente, e uma solução é possível. Agora que nós temos todas as operações de Foo que desejamos exportadas pela interface de componente IFoo, tudo o que resta é entregar ao componente cliente uma referência opaca a um objeto Foo. O componente cliente da interface nunca necessitará resolver (ou de-referenciar) esta referência; ele apenas mantém este valor para usá-lo como argumento de chamada a uma operação da interface IFoo. [2]&lt;br /&gt;&lt;br /&gt;Endereços de memória do C++ podem ser guardados apropriadamente na memória do Java como um valor do tipo Long. Assim, o valor de retorno da operação Foo_create é resolvido pelo seguinte "type map":&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  // este é o objeto retornado pela chamada JNI&lt;br /&gt;  jlong jresult = 0;&lt;br /&gt;  // este é o objeto retornado pela função C++&lt;br /&gt;  Foo* result = NULL;&lt;br /&gt;&lt;br /&gt;  // type map&lt;br /&gt;  result = new Foo(arg1_str); // vide type map anterior&lt;br /&gt;  *(Foo **)&amp;amp;jresult = result;&lt;br /&gt;&lt;br /&gt;  // por fim...&lt;br /&gt;  return jresult;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;e a operação na interface de componente Java/JNI terá a seguinte forma:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  public static native jlong Foo_create (String name);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Assim, o programa Java chamador de Foo_create através desta interface receberá um valor Long que contém o endereço, na memória do C++, do objeto Foo recém-criado. A operação Foo_get_name através desta interface terá a seguinte forma:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  public static native String Foo_get_name (jlong foo);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;sendo que o valor de retorno da operação Foo_get_name do componente IFoo será "marshalled" pelo "type map" como já vimos anteriormente.&lt;br /&gt;&lt;br /&gt;Havendo resolvido o problema da possibilidade de referenciar, de maneira opaca, um objeto Foo da memória do C++ na memória do Java, e o problema de chamar operações da classe Foo em C++, podemos então criar uma classe Foo em Java cujo único propósito é imitar a classe Foo em C++ por conveniência.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Foo {&lt;br /&gt;&lt;br /&gt;  private Long cPtr;&lt;br /&gt;&lt;br /&gt;  // @Override&lt;br /&gt;  public void finalize () {&lt;br /&gt;    delete();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void delete () {&lt;br /&gt;    IFooJNI.Foo_delete(cPtr);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public Foo (String name) {&lt;br /&gt;    cPtr = IFooJNI.Foo_new(name);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public String ask_question (String question) {&lt;br /&gt;    return IFooJNI.Foo_ask_question(cPtr, question);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public String get_name () {&lt;br /&gt;    return IFooJNI.Foo_get_name(cPtr);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Desta forma concretizamos uma forma ideal de interoperabilidade entre Java e C++ onde, para cara classe C++, há uma classe Java equivalente, responsável por esconder as chamadas à interface de componente JNI que, por sua vez, é responsável por realizar o transporte de informação através do umbral dos componentes.&lt;br /&gt;&lt;br /&gt;Nestes exemplos ocultamos o fato de que, para a JNI, é necessário não somente um componente Java/JNI mas também um componente C++/JNI além do próprio componente que implementa a interface IFoo; também não lidamos com os casos em que registramos "objetos callback" criados no Java em sistemas C++; não lidamos com a vontade de transportar exceções disparadas em C++ de volta para o chamador Java; entre outras coisas de que não falamos.&lt;br /&gt;&lt;br /&gt;[1] É claro que um projeto pode se utilizar da noção de componentes de uma forma restrita, para obter um conjunto restrito de benefícios, abandonando esta restrição; é possível, por exemplo, obter os benefícios de recompilação veloz e carga de código por demanda abandonando a possibilidade de distribuir os componentes de modo a mantê-los sempre no mesmo espaço de memória e permitir o uso convencional de ponteiros.&lt;br /&gt;&lt;br /&gt;[2] Em projetos de sistemas com componentes é comum que esta idéia do "endereço opaco" seja generalizada para qualquer tipo de informação "opaca" que seja capaz de identificar univocamente um objeto de Foo no domínio do componente Foo; por exemplo, um "nome", ou um GUID, ou outra coisa qualquer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-1424165641738543851?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/1424165641738543851/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=1424165641738543851' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/1424165641738543851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/1424165641738543851'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2008/05/projeto-orientado-componentes-parte-iv.html' title='Projeto Orientado a Componentes, parte IV'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-2363661614867857949</id><published>2008-04-29T22:57:00.006-03:00</published><updated>2008-05-08T15:28:08.776-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Projeto Orientado a Componentes, parte III</title><content type='html'>Agora, uma pausa para reflexão. Esta dicotomia interface versus implementação é difícil de definir. Por baixo dos panos nós temos memória de onde nós lemos e para onde nós escrevemos. O que caracteriza uma interface e o que a distingue de uma implementação?&lt;br /&gt;&lt;br /&gt;Essa pergunta só pode ser respondida em um determinado contexto. Um bom sistema escrito em assembler talvez tenha interfaces mais bem definidas que um mau sistema escrito em Java. Porém, está claro para a indústria que certos mecanismos de linguagem favorecem o estabelecimento de boas interfaces no sistema implementado.&lt;br /&gt;&lt;br /&gt;Além disso, a noção de interface surge diante de um problema de substituição. É interface aquilo que, mantendo-se estável, permite a substituição daquilo que é implementação. Porém, o que é este &lt;span style="font-weight: bold;"&gt;permite&lt;/span&gt;? Este permite, quando caracterizado, por conseguinte caracteriza o que é interface.&lt;br /&gt;&lt;br /&gt;Suponha um sistema escrito em C++ por uma equipe que considera irrisório o tempo de recompilação do código-fonte. Neste contexto, podemos seguramente aceitar que a seguinte substituição mantém estável uma interface.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;antes&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Foo {&lt;br /&gt;public:&lt;br /&gt;&lt;br /&gt;Foo ();&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;mutate_stuff ();&lt;br /&gt;&lt;br /&gt;int&lt;br /&gt;observe_stuff () const;&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;Bar* m_bar;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;depois&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Foo {&lt;br /&gt;public:&lt;br /&gt;&lt;br /&gt;Foo ();&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;mutate_stuff ();&lt;br /&gt;&lt;br /&gt;int&lt;br /&gt;observe_stuff () const;&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;int m_cache;&lt;br /&gt;shared_ptr&amp;lt;bar&amp;gt; m_bar;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Após a alteração acima e uma recompilação o sistema continua a funcionar normalmente. [1] Dizendo de forma mais extensa: neste contexto, a substituição realizada não altera propriedades observáveis externamente da classe, de modo que do ponto de vista de um observador, a classe mantém estável sua interface. (Apenas membros privados foram alterados.)&lt;br /&gt;&lt;br /&gt;Agora vamos alterar as nossas premissas. O tempo de recompilação desse sistema é enorme e o ciclo de testes não pode esperar, de modo que a estrutura de classes do sistema foi particionada e esta classe mora dentro de um objeto compartilhado, uma biblioteca dinâmica.&lt;br /&gt;&lt;br /&gt;A equipe realiza a substituição, recompila o objeto compartilhado e o entrega a uma equipe de testes.&lt;br /&gt;E os testes falham miseravelmente.&lt;br /&gt;&lt;br /&gt;Isto acontece porque, neste novo contexto, há mais propriedades observáveis a considerar, que devem se manter estáveis -- que fazem parte da interface da classe.&lt;br /&gt;Neste caso, o layout de um objeto da classe Foo é uma propriedade observável; um programa compilado criando objetos da definição &lt;span style="font-weight: bold;"&gt;antes&lt;/span&gt; criará objetos com um layout diferente daquele esperado pelo objeto compartilhado que espera objetos dada a definição &lt;span style="font-weight: bold;"&gt;depois&lt;/span&gt;.&lt;br /&gt;A definição &lt;span style="font-weight: bold;"&gt;depois&lt;/span&gt; tem um int no &lt;span style="font-style: italic;"&gt;offset&lt;/span&gt; onde a definição &lt;span style="font-weight: bold;"&gt;antes&lt;/span&gt; tinha um ponteiro, ela ocupa mais memória etc.&lt;br /&gt;&lt;br /&gt;Podemos dizer que o primeiro caso é o caso de um projeto orientado a objetos, onde a alteração de elementos privados da classe não altera a interface; e podemos dizer que o segundo caso é o caso de um projeto orientado a componentes, onde a alteração do layout na memória de uma classe altera sua interface.&lt;br /&gt;&lt;br /&gt;Como no segundo caso nós estamos violando a interface do componente, nós não podemos substituir o componente de antes pelo componente de depois impunemente. Dito de trás para a frente, pelo fato de não podermos substituir o componente de antes pelo componente de depois, por definição estamos violando sua interface.&lt;br /&gt;&lt;br /&gt;Imagine então o que acontece em um sistema spaghetti, onde todas as classes mantém referência a todas as outras classes; uma violação de interface em um "componente" perturbará implacavelmente todos os outros "componentes".&lt;br /&gt;&lt;br /&gt;Quando projetamos um sistema pensando em componentes, ou quando desejamos aplicar a idéia forte de interface para melhorar o nosso projeto diminuindo o acoplamento entre as coisas que são distintas, é útil usar das ferramentas à disposição para dar &lt;span style="font-weight: bold;"&gt;forma&lt;/span&gt; ao que é uma interface.&lt;br /&gt;&lt;br /&gt;Linguagens que se propõe a facilitar o desenvolvimento de componentes, como Java e C#, possuem como parte integrante do seu vocabulário e mecanismo nativo uma &lt;span style="font-style: italic;"&gt;interface&lt;/span&gt; em contraste com as classes. Normalmente algo do tipo:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;interface IFoo {&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;mutate_stuff ();&lt;br /&gt;&lt;br /&gt;int&lt;br /&gt;observe_stuff () const;&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Em C++ não existe uma construção análoga mas é possível emulá-la integralmente usando classes, da seguinte maneira:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class IFoo {&lt;br /&gt;&lt;br /&gt;virtual&lt;br /&gt;void&lt;br /&gt;mutate_stuff () = 0;&lt;br /&gt;&lt;br /&gt;virtual&lt;br /&gt;int&lt;br /&gt;observe_stuff () const = 0;&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(O leitor astuto observará que esta construção-interface não possui atributos.)&lt;br /&gt;&lt;br /&gt;O propósito de usar construções como estas é evidenciar a natureza destes elementos como interfaces -- aquilo que se deseja manter estável -- e diminuir a chance disto que é interface ser inadvertidamente alterado -- causando o desastre. A construção-interface é a melhor amiga do projetista de componentes, permitindo a representação de um conceito de projeto diretamente na linguagem do código-fonte, restringindo as possibilidades de violação durante o processo de implementação, ou ao menos tornando a (necessidade de) violação claramente evidente.&lt;br /&gt;&lt;br /&gt;Infelizmente para nós nem tudo que existe na fronteira de um componente pode ser uma interface, já que é preciso comunicar coisas de um componente para outro. E quem pode viver comunicando apenas doubles e bools? Nós queremos comunicar objetos.&lt;br /&gt;&lt;br /&gt;Além disso, as construções-interface não são garantia de estabilidade de interfaces, já que há mais sobre o que é publicamente observável em um objeto que sua estrutura: há o seu comportamento.&lt;br /&gt;&lt;br /&gt;[1] Estamos, naturalmente, assumindo que o programador não é louco e que a alteração tem algum sentido, exatamente como aparenta ter.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-2363661614867857949?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/2363661614867857949/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=2363661614867857949' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/2363661614867857949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/2363661614867857949'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2008/04/projeto-orientado-componentes-parte-iii.html' title='Projeto Orientado a Componentes, parte III'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-8839494803282192683</id><published>2008-04-28T22:36:00.005-03:00</published><updated>2008-05-08T15:28:23.390-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Projeto Orientado a Componentes, parte II</title><content type='html'>Quando dizemos que componentes são por definição intercambiáveis estamos continuando uma longa tradição de bons projetistas de bons sistemas, cujo conjunto de características sempre integrará, por mais sofisticada a metodologia e/ou a nomenclatura, a aplicação da &lt;span style="font-weight: bold;"&gt;separação entre interface e implementação&lt;/span&gt;. [1]&lt;br /&gt;&lt;br /&gt;Se a interface continua a mesma, podemos substituir a implementação sem perturbar o comportamento do sistema. Obviamente que o comportamento do sistema deve mudar de alguma forma, senão trocar a porcaria do componente não teria propósito. Esperamos, portanto, que erros sejam corrigidos (de modo que o sistema de fato funcione como deveria), ou que o desempenho aumente (de modo que o sistema funcione antes que eu caia no sono) ou sei lá.&lt;br /&gt;&lt;br /&gt;Aplicávamos esta distinção já na era do projeto estruturado; e no projeto essencial; e no projeto orientado a objetos; e agora no projeto orientado a componentes e aplicaremos no projeto orientado a serviços quando finalmente este troço alcançar a plebe.&lt;br /&gt;&lt;br /&gt;Em um sistema orientado a objetos, nós temos tipicamente dois elementos em evidência como &lt;span style="font-weight: bold;"&gt;detalhe de implementação&lt;/span&gt;: a estrutura de um objeto, e as instruções levadas a cabo por seus métodos. Nós queremos liberdade para alterar a estrutura de um objeto e queremos liberdade para alterar a instruções executadas por seus métodos. (Há mais por debaixo do pano, como sempre.)&lt;br /&gt;&lt;br /&gt;Em um sistema orientado a componentes, um terceiro elemento surge ofuscando, como se fosse, os outros dois; o componente propriamente dito. Entendemos que um componente possui uma interface e uma implementação; sendo a implementação de um componente composta por inúmeras classes. Além disso, um componente é um artefato componente (heh) de um sistema implantado; é parte da definição de componente que este seja intercambiável por um outro, que implemente a mesma interface, em um sistema implantado -- em contraste com um tipo de substituição que exige recompilação.&lt;br /&gt;&lt;br /&gt;Esta última restrição, quando posta no contexto dos sistemas operacionais reais, com seus &lt;span style="font-style: italic;"&gt;linkers&lt;/span&gt; e &lt;span style="font-style: italic;"&gt;loaders&lt;/span&gt; reais, nos trás à &lt;span style="font-style: italic;"&gt;crux&lt;/span&gt; do problema de projeto orientado a componentes: a implementação de uma classe integrante de um componente &lt;span style="font-weight: bold;"&gt;absolutamente não pode&lt;/span&gt; depender de um detalhe de implementação de uma classe integrante de outro componente.&lt;br /&gt;&lt;br /&gt;Observe que esta restrição não é exatamente uma novidade, já que bons sistemas isolarão módulos através de interfaces para aumentar a coesão e diminuir o acoplamento; porém, quando componentes entram na jogada, a metodologia exige uma restrição mais forte.&lt;br /&gt;&lt;br /&gt;(De fato, esta restrição metodológica se torna uma impossibilidade tecnológica assim que os componentes são levados ao próximo estágio, passam a não mais morar no mesmo espaço de memória virtual, e começam a ser chamados "distribuídos" ou "serviços".) [2]&lt;br /&gt;&lt;br /&gt;É por esta razão que os líderes do Projeto Spaghetti falharão em "componentizar" seu sistema; mesmo que, à primeira vista, seja possível seccionar sua estrutura de classes em artefatos binários distintos.&lt;br /&gt;&lt;br /&gt;[1] Nós, filhos da cultura européia, nem escrevendo programas nos livramos da dicotomia corpo versus espírito. Nem imagino o que seria uma metodologia de desenvolvimento de sistemas desenvolvida por monges taoístas chineses.&lt;br /&gt;&lt;br /&gt;[2] E portanto, domar a restrição metodológica significa poder conviver com a impossibilidade tecnológica e eventualmente programar os sistemas do futuro.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-8839494803282192683?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/8839494803282192683/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=8839494803282192683' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8839494803282192683'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8839494803282192683'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2008/04/projeto-orientado-componentes-parte-ii.html' title='Projeto Orientado a Componentes, parte II'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-6691953570210247646</id><published>2008-04-28T21:34:00.002-03:00</published><updated>2008-04-28T21:59:19.235-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Projeto Orientado a Componentes, parte I</title><content type='html'>Ano passado fiz um curso de extensão em Projeto Orientado a Componentes com UML; na época, eu estava progredindo na minha capacidade de construir modelos mentais de projetos de &lt;span style="font-style: italic;"&gt;software&lt;/span&gt; orientados a objeto e já havia lido bastante sobre &lt;span style="font-style: italic;"&gt;web services&lt;/span&gt; e arquiteturas orientada a serviços.&lt;br /&gt;&lt;br /&gt;O mais interessante sobre os Componentes é a maneira como eles dão um nó na sofisticação aparente dos sistemas e obrigam o projetista a voltar aos básicos. Digo isso porque estes sistemas são &lt;span style="font-weight: bold;"&gt;aparentemente&lt;/span&gt; sofisticados; na prática, eles apresentam &lt;span style="font-weight: bold;"&gt;baixa coesão&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;alto acoplamento&lt;/span&gt;, significando que elementos deste sistema se relacionam diretamente com praticamente todos os outros de maneira &lt;span style="font-style: italic;"&gt;ad hoc&lt;/span&gt;, fenômeno que, em sua forma mais concreta, denomina-se &lt;span style="font-weight: bold;"&gt;código spaghetti&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;É possível construir um sistema orientado a objetos onde todos os objetos conhecem ponteiros para todos os outros, ou praticamente todos os outros, usando truques safados como embrulhar todo mundo em &lt;span style="font-weight: bold;"&gt;shared_ptr&lt;/span&gt; e tornando todas as classes &lt;span style="font-weight: bold;"&gt;enable_shared_from_this&lt;/span&gt; e olerê olará. Isto, é claro, se você tem um mínimo de conhecimento sobre C++ contemporâneo -- e se você está de fato escrevendo seu sistema em C++! -- e se você se importa com a memória. O sistema acima é "orientado a objetos". Muitos deles, embolados entre si.&lt;br /&gt;&lt;br /&gt;Quando você se propõe a fazer sistemas orientados a componentes, porém, o buraco se alarga e se torna mais profundo. Os componentes existem com o propósito de serem intercambiáveis. Você &lt;span style="font-weight: bold;"&gt;não tem&lt;/span&gt; componentes se você não pode tirar um deles e colocar outro no lugar &lt;span style="font-weight: bold;"&gt;impunemente&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Frequentemente, os responsáveis por sistemas spaghetti ou aberrações similares, diante dos problemas insuportáveis causados inevitavelmente pela baixa coesão e pelo alto acoplamento, tentam "componentizar" seus sistemas com o intuito de obter os benefícios maravilhosos oferecidos pelos livros.&lt;br /&gt;&lt;br /&gt;Vamos, então, pegar pedaços do sistema e enfiar dentro de DLLs!&lt;br /&gt;&lt;br /&gt; Certamente isto não funciona.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-6691953570210247646?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/6691953570210247646/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=6691953570210247646' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6691953570210247646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6691953570210247646'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2008/04/projeto-orientado-componentes-parte-i.html' title='Projeto Orientado a Componentes, parte I'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-3194820270244944501</id><published>2008-04-06T19:24:00.003-03:00</published><updated>2008-04-06T19:30:52.354-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Projeto: Eclipse + CppUnit</title><content type='html'>Estou prestes a apresentar para o ccppbrasil.org um projeto de integração da CppUnit com o Eclipse TPTP.&lt;br /&gt;&lt;br /&gt;Será uma oportunidade interessante de aprender a desenvolver sobre a plataforma OSGi e uma maneira de estimular a comunidade a aplicar as técnicas de testes de unidade.&lt;br /&gt;&lt;br /&gt;A arquitetura do TPTP Test é assim: para um determinado "tipo de teste" registra-se um adaptador de implantação, um adaptador de ambiente e um adaptador de execução, bem como um &lt;span style="font-style: italic;"&gt;runner&lt;/span&gt; para este "tipo de teste" no agente remoto.&lt;br /&gt;&lt;br /&gt;A tarefa será implementar esses adaptadores para programas executáveis nativos e bibliotecas compartilhadas, resolvendo LD_LIBRARY_PATH e assuntos relacionados, depois implementar uma biblioteca de suporte em C para que programas joguem na saída padrão o histórico de execução da forma correta e por fim implementar com um &lt;span style="font-style: italic;"&gt;wrapper&lt;/span&gt; Java um &lt;span style="font-style: italic;"&gt;runner&lt;/span&gt; para suites de teste CppUnit na forma de &lt;span style="font-style: italic;"&gt;plug-in&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Na verdade as tarefas ainda estão se abrindo porque não consegui dominar o problema de projeto completamente, o que me aborreceu um pouco, já que vou passar a semana ocupado com outros assuntos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-3194820270244944501?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/3194820270244944501/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=3194820270244944501' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/3194820270244944501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/3194820270244944501'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2008/04/projeto-eclipse-cppunit.html' title='Projeto: Eclipse + CppUnit'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-5053233832723769203</id><published>2008-04-02T23:29:00.003-03:00</published><updated>2008-04-02T23:53:06.339-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Encontro de Nerds em São Paulo</title><content type='html'>Ora, &lt;a href="http://picasaweb.google.com/ccppmeetings/4oEncontroDeProgramadoresEAficcionadosDoGrupoCCBrasilSampa"&gt;aqui estamos nós&lt;/a&gt;!&lt;br /&gt;O Encontro foi muito bom, evoluindo o formato do anterior.&lt;br /&gt;Os nerds são inteligentes e conhecedoras das coisas, e bebem bastante cerveja e são engraçados demais.&lt;br /&gt;Nosso trabalho continua no site &lt;a href="http://ccppbrasil.org/"&gt;ccppbrasil.org&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-5053233832723769203?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/5053233832723769203/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=5053233832723769203' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/5053233832723769203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/5053233832723769203'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2008/04/encontro-de-nerds-em-so-paulo.html' title='Encontro de Nerds em São Paulo'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-423385270669219131</id><published>2008-03-29T06:18:00.003-03:00</published><updated>2008-03-29T06:25:13.801-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Quarto Encontro CCPP Brasil</title><content type='html'>Cheguei há pouco na rodoviária de São Paulo.&lt;br /&gt;&lt;br /&gt;Entrei em uma lan house pra anotar os endereços de que eu precisava. ¬¬&lt;br /&gt;&lt;br /&gt;Cheguei cedo demais aqui; o ônibus fez a viagem em cinco horas e meia.&lt;br /&gt;A turma só vai acordar depois das 07h, provavelmente às 08h.&lt;br /&gt;&lt;br /&gt;Vou passar o tempo comendo e fumando.&lt;br /&gt;&lt;br /&gt;Desta vez vou ficar hospedado no Formule One Jardins.&lt;br /&gt;A estação de metrô da vez é Trianon-Masp.&lt;br /&gt;Pra facilitar a minha vida comecei &lt;a href="http://maps.google.com/maps/ms?hl=pt-BR&amp;amp;ptab=2&amp;amp;ie=UTF8&amp;amp;oe=UTF8&amp;amp;msa=0&amp;amp;msid=109942149518875622131.00044948f80b64f823f88"&gt;este mapa&lt;/a&gt; com marcadores para as estações do metrô.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-423385270669219131?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/423385270669219131/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=423385270669219131' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/423385270669219131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/423385270669219131'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2008/03/quarto-encontro-ccpp-brasil.html' title='Quarto Encontro CCPP Brasil'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-7109447482082637298</id><published>2008-03-24T11:17:00.003-03:00</published><updated>2008-03-24T11:27:44.210-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>OpenMP</title><content type='html'>Reavaliar as hipóteses vigentes é sempre interessante quando você já possui alguma experiência; um retorno à "infância" do aprendizado, talvez, a uma época em que a sua sensação de segurança era mínima.&lt;br /&gt;&lt;br /&gt;Acrescentar uma anotação tão singela quanto:&lt;br /&gt;&lt;blockquote&gt;#pragma omp parallel&lt;br /&gt;&lt;/blockquote&gt;causou um desastre tremendo em um &lt;span style="font-style: italic;"&gt;loop &lt;/span&gt;pequenininho dentro de pixman-mmx.c nesse fim de semana, experimentando com o André um novo caminho de otimização.&lt;br /&gt;&lt;br /&gt;Se o seu compilador implementa OpenMP a diretiva acima transforma o bloco do &lt;span style="font-style: italic;"&gt;loop &lt;/span&gt;seguinte de modo a despachar iterações individuais a um time de &lt;span style="font-style: italic;"&gt;threads &lt;/span&gt;de trabalho.&lt;br /&gt;&lt;br /&gt;Quando a hipótese de que uma iteração será seguida de outra some dependências entre acessos a dados surgem: enquanto uma iteração lê um endereço outra iteração escreve nesse enredeço, &lt;span style="font-weight: bold;"&gt;boom&lt;/span&gt;. Experimentamos muitos SIGSEGV com este &lt;span style="font-style: italic;"&gt;loop&lt;/span&gt;. Eventualmente a implementação foi transformada de modo a eliminar essas dependências.&lt;br /&gt;&lt;br /&gt;É interessante que se você não tem em mente essa questão não se dará ao trabalho e seus &lt;span style="font-style: italic;"&gt;loops&lt;/span&gt; não terão iterações independentes. Porém, mesmo sem OpenMP, o GCC 4.3 produziu uma melhoria impressionante na execução deste código; certamente porque seus otimizadores aproveitaram novas oportunidades oferecidas por iterações livres de &lt;span style="font-style: italic;"&gt;side effects&lt;/span&gt; observáveis.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-7109447482082637298?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/7109447482082637298/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=7109447482082637298' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7109447482082637298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7109447482082637298'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2008/03/openmp.html' title='OpenMP'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-6071450799067715083</id><published>2008-03-15T13:06:00.001-03:00</published><updated>2008-03-15T13:11:10.755-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>ccppbrasil.org</title><content type='html'>yo! _o/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-6071450799067715083?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/6071450799067715083/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=6071450799067715083' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6071450799067715083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6071450799067715083'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2008/03/ccppbrasilorg.html' title='ccppbrasil.org'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-41369137033085909</id><published>2008-01-13T06:44:00.000-02:00</published><updated>2008-01-13T06:47:12.984-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Palestra em Sampa</title><content type='html'>Próximo sábado, dia 19, darei uma palestra em Sampa com o seguinte título:&lt;br /&gt;&lt;br /&gt;"C++0x - Novas características de suporte a projetos de bibliotecas genéricas"&lt;br /&gt;&lt;br /&gt;Estou um pouco excitado e um pouco nervoso com essa oportunidade.&lt;br /&gt;&lt;br /&gt;Participarei do terceiro encontro do Grupo de Usuários C/C++.&lt;br /&gt;A programação do evento está &lt;a href="http://www.cbrasil.org/wiki/index.php?title=Defini%C3%A7%C3%A3o_da_cidade_e_data"&gt;aqui&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-41369137033085909?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/41369137033085909/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=41369137033085909' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/41369137033085909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/41369137033085909'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2008/01/palestra-em-sampa.html' title='Palestra em Sampa'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-6153894815825215684</id><published>2007-05-31T11:41:00.000-03:00</published><updated>2007-05-31T11:49:12.108-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Fedora 7 nasceu</title><content type='html'>&lt;a href="http://fedoraproject.org/"&gt;Fedora&lt;/a&gt; é o sistema operacional livre que eu uso em casa.&lt;br /&gt;Eu recomendo a todos e normalmente estou disposto a dar suporte voluntário (&lt;span style="font-style: italic;"&gt;caveat emptor&lt;/span&gt;) para resolver problemas.&lt;br /&gt;&lt;br /&gt;O ambiente de trabalho do Fedora é o &lt;a href="http://www.gnome.org/"&gt;GNOME&lt;/a&gt; e ele é muito bonito.&lt;br /&gt;&lt;br /&gt;A versão 7 do sistema foi lançada hoje.&lt;br /&gt;Vou instalar nesse fim de semana e dar o meu parecer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-6153894815825215684?l=blog.pedro.lamarao.nom.br'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/6153894815825215684/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=6153894815825215684' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6153894815825215684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6153894815825215684'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2007/05/fedora-7-nasceu.html' title='Fedora 7 nasceu'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry></feed>