<?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' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2393468880781945441</id><updated>2012-02-16T08:37:29.161-02:00</updated><category term='sistemas'/><category term='cxx'/><category term='random'/><title type='text'>Pedro sobre Software</title><subtitle type='html'>Artigos sobre usar software e fazer software. E, às vezes, algum apócrifo sobre hardware.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://software.pedro.lamarao.nom.br/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2393468880781945441/posts/default/-/cxx'/><link rel='alternate' type='text/html' href='http://software.pedro.lamarao.nom.br/search/label/cxx'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2393468880781945441.post-3040098449476545995</id><published>2012-02-09T15:40:00.002-02:00</published><updated>2012-02-09T15:42:31.392-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><title type='text'>Servidor e usuário COM na mesma "solution"</title><content type='html'>&amp;nbsp;Um dos objetivos da próxima iteração no meu projeto atual é quebrar o sistema em mais pedaços, e levantar os pedaços um nível de abstração até componentes COM.&lt;br /&gt;Uma das consequências é substituir diversas ligações mais estáticas e torná-las ligações mais dinâmicas através do COM.&lt;br /&gt;&lt;br /&gt;Tipicamente, um programa usuário de um componente COM, escrito para o Visual Studio, usará a diretiva &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#import &lt;/span&gt;para incluir na unidade de tradução C++ as declarações necessárias. Isso implica que o componente deve estar instalado na máquina que constrói o programa.&lt;br /&gt;&lt;br /&gt;O que fazer quando o componente em questão está no mesmo lote de construção que o programa usuário? A solução inicial é criar uma dependência de construção tal que o componente seja sempre construído primeiro, e usar um &lt;i&gt;post-build event&lt;/i&gt; ao projeto do componente para registrá-lo no sistema. Desse modo, na construção do programa, o ambiente estará correto.&lt;br /&gt;&lt;br /&gt;Eu considero este arranjo prejudicial. Minha melhor razão é esta: o servidor de construção&lt;i&gt;&lt;/i&gt; principal é um Windows Server 2008 x86-64, onde o usuário que constrói não é membro do grupo &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Administradores&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Evitando debater essa opinião, caminhamos para uma alternativa. Apesar de &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#&lt;/span&gt;import ser a maneira mais fácil de usar o componente, a maneira básica de referenciar componentes (e interfaces) COM é através da IDL que os definem.&lt;br /&gt;&lt;br /&gt;Desse modo, o desenvolvedor incluiria os arquivos IDL que definem o componente (e suas interfaces) no projeto do programa. Construir arquivos IDL é gerar arquivos &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.h&lt;/span&gt; e &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.c&lt;/span&gt;, que devem compor o programa como de costume.&lt;br /&gt;&lt;br /&gt;Mas como lidar com um componente ainda em desenvolvimento, cujas definições em IDL estão ainda incompletas ou não são definitivas? É, no mínimo, um saco copiar os arquivos IDL para todos os programas usuários (que, no meu caso, são vários) a cada vez que esses arquivos são modificados. Por princípio, desejamos definir as coisas em um único lugar, e referenciar este lugar em todos os outros lugares onde as coisas são necessárias.&lt;br /&gt;&lt;br /&gt;Como reusar arquivos IDL dessa maneira? Infelizmente, não é possível usar &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#import&lt;/span&gt; com arquivos IDL; além disso, não faz sentido usar &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#include&lt;/span&gt;. Arquivos IDL devem ser compilados junto com o programa, não incluídos diretamente em unidades de tradução C++.&lt;br /&gt;&lt;br /&gt;A base da minha solução, com o Visual Studio, é incluir os arquivos IDL presentes no projeto do componente em todos os projetos usuários usando o comando &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Add Existing Item&lt;/span&gt; do menu &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Project&lt;/span&gt;. Este comando insere uma referência aos arquivos selecionados no lote de construção do projeto-alvo &lt;b&gt;sem copiar &lt;/b&gt;estes arquivos.&lt;br /&gt;&lt;br /&gt;Essa técnica não funciona para componentes definidos em múltiplos arquivos IDL que fazem referência uns aos outros através da diretiva &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import&lt;/span&gt;. (Não confundir!) O &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;midl.exe&lt;/span&gt; provavelmente não será capaz de ajustar os caminhos de &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import &lt;/span&gt;para o novo contexto -- o local de construção do programa é diferente do local de construção do componente. O arquivo &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;A.idl &lt;/span&gt;referencia &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;"B.idl"&lt;/span&gt; mas este arquivo não existe no local dos fontes do programa, mas sim no local dos fontes do componente.&lt;br /&gt;&lt;br /&gt;A solução para essa situação é ajustar a configuração &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Additional Include Directories &lt;/span&gt;na aba &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;MIDL &lt;/span&gt;das &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Configuration Properties&lt;/span&gt; do projeto.&lt;br /&gt;&lt;br /&gt;Com essa configuração ajustada, os arquivos &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.h&lt;/span&gt; e &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.c&lt;/span&gt; correspondentes às IDL serão criados no local dos fontes do programa, como desejado. Estes arquivos devem ser incluídos da forma costumeira na construção do programa. Novamente, a técnica não funcionará para componentes definidos em múltiplos arquivos IDL, devido a um desacordo entre o &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;midl.exe&lt;/span&gt; e o Visual Studio. A configuração padrão produzirá, para &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Foo.idl&lt;/span&gt;, arquivos &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Foo_h.h&lt;/span&gt;; porém, no texto gerado pelo &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;midl.exe&lt;/span&gt;, ocorrerá &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#include "Foo.h"&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;A solução para essa situação é ajustar a configuração &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Header File &lt;/span&gt;na aba &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Output&lt;/span&gt;, na aba &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;MIDL &lt;/span&gt;das &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Configuration Properties&lt;/span&gt; para o valor &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$(Filename).h&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Com essa configuração ajustada, os arquivos gerados terão texto e nome corretos, e será possível compilar o programa. Aqui, um último problema pode surgir, caso o projeto do programa use PCH. Muito provavelmente, o arquivo PCH terá sido compilado como unidade de tradução C++. Porém, o &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;midl.exe &lt;/span&gt;gera arquivos C e não arquivos C++. Não é permitido incluir PCHs C++ em unidades de tradução C. É preciso desabilitar PCH para todo o projeto, ou especificamente para os arquivos C gerados. Como fazer isso fica como exercício para o leitor.&lt;br /&gt;&lt;br /&gt;Atenção: esta técnica permitirá ao programa incluir as declarações necessárias ao uso do componente; porém, as declarações disponíveis serão muito mais simples que o tipicamente injetado pelo &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#import&lt;/span&gt;. Sugiro o uso de &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ATL::CComPtr&lt;/span&gt; ou, se não for possível usar ATL, o uso de &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;_COM_SMARTPTR_TYPEDEF&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2393468880781945441-3040098449476545995?l=software.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://software.pedro.lamarao.nom.br/feeds/3040098449476545995/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://software.pedro.lamarao.nom.br/2012/02/servidor-e-usuario-com-na-mesma.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2393468880781945441/posts/default/3040098449476545995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2393468880781945441/posts/default/3040098449476545995'/><link rel='alternate' type='text/html' href='http://software.pedro.lamarao.nom.br/2012/02/servidor-e-usuario-com-na-mesma.html' title='Servidor e usuário COM na mesma &quot;solution&quot;'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2393468880781945441.post-1037193415335478334</id><published>2011-03-25T13:32:00.000-03:00</published><updated>2011-03-25T13:32:45.993-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><title type='text'>Visual Studio 6: debugger vs. Unicode string</title><content type='html'>Gente, depois de uma eternidade de sofrimento para interpretar (TCHAR *) no debugger do Visual Studio 6, eu acabei de descobrir, nesse minuto!, que existe uma opção chamada "Display Unicode String" e que &lt;b&gt;esta opção não está marcada na configuração padrão&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Em Options, Debug. Você clica nela e o debugger mostra strings de wchar_t.&lt;br /&gt;&lt;br /&gt;Por quê!?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2393468880781945441-1037193415335478334?l=software.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://software.pedro.lamarao.nom.br/feeds/1037193415335478334/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://software.pedro.lamarao.nom.br/2011/03/visual-studio-6-debugger-vs-unicode.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2393468880781945441/posts/default/1037193415335478334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2393468880781945441/posts/default/1037193415335478334'/><link rel='alternate' type='text/html' href='http://software.pedro.lamarao.nom.br/2011/03/visual-studio-6-debugger-vs-unicode.html' title='Visual Studio 6: debugger vs. Unicode string'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2393468880781945441.post-3070179289005525902</id><published>2010-09-09T11:32:00.000-03:00</published><updated>2010-09-09T11:32:26.851-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><title type='text'>Análise Sintática Incremental</title><content type='html'>Em 2008, &lt;a href="http://groups.google.com/group/ccppbrasil/browse_thread/thread/cbf5fd808372a60b/5d86ba2ed32acdd6"&gt;perguntei&lt;/a&gt; na ccppbrasil.org sobre uma boa maneira de produzir &lt;i&gt;parsers&lt;/i&gt; incrementais.&lt;br /&gt;&lt;br /&gt;Dois anos depois, pude parar e estudar o manual do Bison o suficiente para descobrir ali o meu objetivo: &lt;i&gt;push parsers&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Este exemplo do manual é precisamente o que eu quero:&lt;br /&gt;&lt;br /&gt;&lt;pre class="example"&gt;int status;&lt;br /&gt;     yypstate *ps = yypstate_new ();&lt;br /&gt;     do {&lt;br /&gt;       status = yypush_parse (ps, yylex (), NULL);&lt;br /&gt;     } while (status == YYPUSH_MORE);&lt;br /&gt;     yypstate_delete (ps);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Meu objetivo é aplicar esta técnica para produzir o decodificador de mensagens de protocolo de aplicação em um servidor baseado em &lt;i&gt;readiness-notification&lt;/i&gt; e &lt;i&gt;non-blocking&lt;/i&gt; I/O.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2393468880781945441-3070179289005525902?l=software.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://software.pedro.lamarao.nom.br/feeds/3070179289005525902/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://software.pedro.lamarao.nom.br/2010/09/analise-sintatica-incremental.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2393468880781945441/posts/default/3070179289005525902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2393468880781945441/posts/default/3070179289005525902'/><link rel='alternate' type='text/html' href='http://software.pedro.lamarao.nom.br/2010/09/analise-sintatica-incremental.html' title='Análise Sintática Incremental'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2393468880781945441.post-5345023746414866916</id><published>2010-08-30T15:37:00.000-03:00</published><updated>2010-08-30T15:37:19.701-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><title type='text'>Por que goto é considerado prejudicial?</title><content type='html'>Recentemente, o Fabiano Vasconcelos abriu uma &lt;a href="http://groups.google.com/group/ccppbrasil/t/179f11adc8c8d634"&gt;discussão&lt;/a&gt; no Grupo de Usuários de C e C++:&lt;br /&gt;&lt;blockquote&gt;De cara eu vi algo aqui um pouco estranho, se que o amigo Márcio me permite comentar: que muitos programadores, inclusive eu (se que posso ser rotulado como programador) foram instruídos com o princípio de NUNCA usar o goto, por ser considerado um mau estilo de programação.&lt;/blockquote&gt;Durante a discussão, o Eduardo Vieira puxou um &lt;a href="http://kerneltrap.org/node/553/2131"&gt;artigo&lt;/a&gt; da KernelTrap sobre uma discussão similar ocorrida no grupo de desenvolvimento do Linux, onde Robert Wilken disse o seguinte:&lt;br /&gt;&lt;blockquote&gt;In general, if you can structure your code properly, you should never need a goto, and if you don't need a goto you shouldn't use it. It's just "common sense" as I've always been taught. Unless you're intentionally trying to write code that's harder for others to read.&lt;/blockquote&gt;É preciso colocar a máxima "goto considered harmful" na perspectiva histórica adequada.&lt;br /&gt;&lt;br /&gt;Acredito que praticamente todo programador treinado nos últimos vinte anos aprendeu a programar com if e while. Essas são as estruturas básicas de programas e aparecem rapidamente nos manuais e nos cursos de programação. Toda linguagem de programação moderna tem if e while, e variantes como switch, for etc.&lt;br /&gt;&lt;br /&gt;Essas coisas são chamadas estruturas de controle porque fazem exatamente isso: controlam a execução do programa, às vezes indo para uma sequência de sentenças, às vezes indo para outra, de acordo com testes explícitos. Arranjar um programa com sequências de sentenças, if e while é fazer programação estruturada.&lt;br /&gt;&lt;br /&gt;Agora, a não ser que algum curso maravilhoso e desconhecido por mim tenha história da programação no seu currículo, este programador provavelmente não percebe que if e while nem sempre existiram e que a programação estruturada foi inventada mais ou menos na década de 70.&lt;br /&gt;&lt;br /&gt;Durante a discussão no grupo de desenvolvimento do Linux, Scott Robert Ladd disse o seguinte:&lt;br /&gt;&lt;blockquote&gt;Your attitude against "goto" is perhaps based upon an excellent but dated article, "Goto Considered Harmful", written by Edsger W. Dijkstra, and published by the ACM in 1968. (A recent reprint can be found at http://www.acm.org/classics/oct95/.) As you can tell from the date, this article predates modern programming languages and idioms; it comes from a time when Fortran ruled, and before Fortran 77 provided significant tools for avoiding spaghetti code.&lt;/blockquote&gt;e mais o seguinte:&lt;br /&gt;&lt;blockquote&gt;Used over short distances with well-documented labels, a "goto" can be more effective, faster, and cleaner than a series of complex flags or other constructs. The "goto" may also be safer and more intuitive than the alternative. A "break" is a goto; a "continue" is a "goto" -- these are statements that move the point of execution explicitly.&lt;/blockquote&gt;Dijkstra, e outros, iniciaram a pequena revolta estruturada e assim ocorreu que diversas linguagens de programação introduziram novidades como if e while. Mas como é possível programar sem if e while?&lt;br /&gt;&lt;br /&gt;Considere este fragmento:&lt;br /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;char * i = input;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;while (*i != '\0')&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;if (*i == SPECIAL) goto exit;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;else ++i;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;:exit&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;return i;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Este fragmento _não_ é o objeto da objeção ao uso de goto. Este fragmento exibe honrada programação estruturada. goto está ali como bem poderia estar break. Tanto faz.&lt;br /&gt;&lt;br /&gt;Agora, observe este fragmento:&lt;br /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;char * i = input;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;:loop&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;if (*i == '\0') goto exit;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;if (*i == SPECIAL) goto exit;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;++i;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;goto loop;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;:exit&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;return i;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br /&gt;Isto é o que você deve evitar.&lt;br /&gt;&lt;br /&gt;O objetivo do combate ao goto era combater a programação não-estruturada, e esse combate foi vencido com a introdução das linguagens estruturadas. Tais linguagens levam o programador naturalmente ao caminho certo e proíbem os maiores absurdos.&lt;br /&gt;&lt;br /&gt;Existem linguagens em que o último fragmento acima era _a única alternativa_. (Ou coisa pior.)&lt;br /&gt;&lt;br /&gt;Em retrospectiva, sabemos que a programação não-estruturada dominante na época causava um modo de pensar não-estruturado sobre os programas, de modo que o "spagetthi code" clássico era um único fluxo de instruções com gotos arbitrários para cima e para baixo, algo muito pior que o último fragmento acima, o tipo de código que eu não saberia construir artificialmente.&lt;br /&gt;&lt;br /&gt;Se você conhece e pratica a programação de acordo com os bons princípios da programação estruturada, não precisa temer o goto. Existem diversas situações excepcionais às quais as estruturas de controle do C não se adequam perfeitamente; aquela que me ocorre com mais frequência são switches dentro de for quando é preciso terminar o for dentro de um case.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;for (char * i = input; *i != '\0'; ++i)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;switch (state)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;{&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;case FOO:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; /* many things */&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; break;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;case BAR:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; if (*i == SPECIAL) goto exit;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; /* many things */&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; break;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;}&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;exit:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Sempre existe uma maneira de remover o goto; nem sempre essa maneira é desejável. O goto acima, cujo label está exatamente na saída do laço, me parece uma parte bastante adequada da estrutura de controle. Java, que não possui goto, permite dizer "break exit", com exatamente o mesmo significado.&lt;br /&gt;&lt;br /&gt;Durante a discussão no grupo de desenvolvimento do Linux, Robert Love disse o seguinte sobre a substituição do goto por outras estruturas:&lt;br /&gt;&lt;blockquote&gt;As a final argument, it does not let us cleanly do the usual stack-esque wind and unwind, i.e.&lt;/blockquote&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;do A&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;if (error) goto out_a;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;do B &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;if (error) goto out_b;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;do C&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;if (error) goto out_c;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;goto out;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;out_c:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;undo C&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;out_b:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;undo B:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;out_a:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;undo A&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;out:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;return ret;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;Now stop this.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2393468880781945441-5345023746414866916?l=software.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://software.pedro.lamarao.nom.br/feeds/5345023746414866916/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://software.pedro.lamarao.nom.br/2010/08/por-que-goto-e-considerado-prejudicial.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2393468880781945441/posts/default/5345023746414866916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2393468880781945441/posts/default/5345023746414866916'/><link rel='alternate' type='text/html' href='http://software.pedro.lamarao.nom.br/2010/08/por-que-goto-e-considerado-prejudicial.html' title='Por que goto é considerado prejudicial?'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2393468880781945441.post-4924649353404381248</id><published>2010-07-06T23:07:00.000-03:00</published><updated>2010-07-06T23:07:36.175-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><title type='text'>Test Driven em C++ cross-compiled é possível</title><content type='html'>afe!&lt;br /&gt;&lt;br /&gt;Enquanto não rola um estudo retrospectivo maneiro, aqui vão minhas primeiras impressões.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;por mais que pareça andar de ré, tenha um porting para o sistema do desenvolvedor, onde a compilação não é cruzada;&lt;/li&gt;&lt;li&gt;não exija frameworks xUnit e faça bilhões de programecos se necessário;&lt;/li&gt;&lt;li&gt;guarde no coração que não é preciso reflection nem mesmo shared objects para aplicar dependency injection;&lt;/li&gt;&lt;li&gt;não despreze a tediosa tarefa de testar parte a parte, pequena parte a pequena parte;&lt;/li&gt;&lt;li&gt;não tenha escrúpulos para satisfazer dependências aleatórias com stubs.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;A maior revelação para mim nesse processo foram os pontos 2, 3 e 5 acima.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Após um longo tempo digerindo o problema, e após diversas discussões sobre que framework de testes usar, por fim completei a tarefa da forma mais tosca possível: cada teste é um programa executável individual. &amp;nbsp;O projeto usa cmake para configurar a construção, e o ctest funciona legal com essa lista de programas de teste.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;O maior esforço nesse processo foi refatorar o código o suficiente para conseguir testar uma unidade isolada realmente. A dificuldade percebida pela equipe desde o início era devido ao acoplamento entre as diversas unidades teóricas do sistema, e a quantidade de código de inicialização de coisas irrelevantes ao teste. Eventualmente tropecei na idéia de dependency injection. Apesar de ser algo que ocorre em super frameworks de componentes empresariais, o conceito é simples e se mostrou aplicável mesmo em um sistema ligado estaticamente, desde que as unidades fossem desacopladas o suficiente uma da outra. No nosso caso, isso se dá na forma de um Factory central para todo o sistema, pré-existente ao meu esforço.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Claro que esse desacoplamento "suficiente" é um graal e nunca ocorre, especialmente em um ambiente tão confortável quanto o da ligação estática -- onde tudo se junta no final numa grande sopa de elementos.&amp;nbsp;Ocorreu que algumas funções que eram parte da unidade mas não eram exercitadas faziam referência a algum nome que acabava indefinido no programa final -- função ou variável extern.&amp;nbsp;Eventualmente realizei que isso simplesmente não tem solução prática e aceitei a seguinte possibilidade: se uma unidade não compila sem uma função de outra unidade, e a função é irrelevante para o teste, vamos enfiar um stub na jogada e ponto final.&amp;nbsp;De certa forma, isso pode ser considerado um Mock do mundo pré-componentização.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Acaba que, por fim, se não lindamente xUnit, meu objeto de manutenção agora possui uma suite de testes de unidade. Entre os vinte e trinta testes bem básicos que eu bolei pra começar, já descobri umas cinco funções implementadas diferente do que o meu projeto previa. O cmake suporta bem a lista de testes e gera um relatoriozinho bem legal.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2393468880781945441-4924649353404381248?l=software.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://software.pedro.lamarao.nom.br/feeds/4924649353404381248/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://software.pedro.lamarao.nom.br/2010/07/test-driven-em-c-cross-compiled-e.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2393468880781945441/posts/default/4924649353404381248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2393468880781945441/posts/default/4924649353404381248'/><link rel='alternate' type='text/html' href='http://software.pedro.lamarao.nom.br/2010/07/test-driven-em-c-cross-compiled-e.html' title='Test Driven em C++ cross-compiled é possível'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2393468880781945441.post-7126722537848820208</id><published>2010-05-15T20:27:00.000-03:00</published><updated>2010-05-15T20:27:49.871-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><title type='text'>C++0x vai mudar sua vida: listas de inicialização</title><content type='html'>Com a nova sintaxe para listas de inicialização, é como se agora houvesse uma notação para o valor literal de praticamente qualquer estrutura de dados.&lt;br /&gt;&lt;br /&gt;Observe meu teste de unidade construindo um "attribute template" PKCS #11 com std::vector direto na inicialização:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;std::vector&lt;ck_attribute&gt; attributes&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; CK_ATTRIBUTE { CKA_CLASS, &amp;amp;object_class, sizeof(object_class) },&lt;br /&gt;&amp;nbsp; CK_ATTRIBUTE { CKA_TOKEN, &amp;amp;on_token, sizeof(on_token) },&lt;br /&gt;&amp;nbsp; CK_ATTRIBUTE { CKA_LABEL, &amp;amp;label, sizeof(label) },&lt;br /&gt;&amp;nbsp; CK_ATTRIBUTE { CKA_APPLICATION, &amp;amp;application, sizeof(application) },&lt;br /&gt;&amp;nbsp; CK_ATTRIBUTE { CKA_VALUE, &amp;amp;data, sizeof(data) }&lt;br /&gt;};&lt;/ck_attribute&gt;&lt;/div&gt;&lt;br /&gt;O segredo da notação está nessa pseudo-gramática:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&amp;nbsp; type-name identifier &lt;/i&gt;{ &lt;i&gt;initializer-list&lt;/i&gt; };&lt;br /&gt;&lt;br /&gt;que é análoga em significado a:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&amp;nbsp; type-name identifier&lt;/i&gt; ( &lt;i&gt;argument-list&lt;/i&gt; );&lt;br /&gt;&lt;br /&gt;ou:&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &lt;i&gt;type-name identifier = type-name &lt;/i&gt;( &lt;i&gt;argument-list&lt;/i&gt; );&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2393468880781945441-7126722537848820208?l=software.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://software.pedro.lamarao.nom.br/feeds/7126722537848820208/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://software.pedro.lamarao.nom.br/2010/05/c0x-vai-mudar-sua-vida-listas-de.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2393468880781945441/posts/default/7126722537848820208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2393468880781945441/posts/default/7126722537848820208'/><link rel='alternate' type='text/html' href='http://software.pedro.lamarao.nom.br/2010/05/c0x-vai-mudar-sua-vida-listas-de.html' title='C++0x vai mudar sua vida: listas de inicialização'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry></feed>
