Slackjeff Wiki

Juntando bits aprendemos juntos

Ferramentas do usuário

Ferramentas do site


prog:guia-de-estudo-c

Diferenças

Aqui você vê as diferenças entre duas revisões dessa página.

Link para esta página de comparações

Ambos lados da revisão anteriorRevisão anterior
Próxima revisão
Revisão anterior
prog:guia-de-estudo-c [2026/02/23 03:12] – [Compiladores] descrição da compilação hrcerqprog:guia-de-estudo-c [2026/03/02 01:49] (atual) – [Compiladores] palavra repetida removida hrcerq
Linha 193: Linha 193:
   - [[prog:guia-de-estudo-c#montagem|Montagem]]   - [[prog:guia-de-estudo-c#montagem|Montagem]]
   - [[prog:guia-de-estudo-c#ligacao|Ligação]]   - [[prog:guia-de-estudo-c#ligacao|Ligação]]
 +
 +Portanto, o mínimo necessário para compilar programas C são um
 +pré-processador, um compilador, um montador e um ligador, além
 +da biblioteca C (que será explicada mais adiante).
  
 As ferramentas que desempenham essas funções podem ou não estar As ferramentas que desempenham essas funções podem ou não estar
-agrupadas em uma mesma coleção (compiladores mais conhecidos, como GCC e +agrupadas em uma mesma coleção. Duas coleções particularmente 
-Clang, por exemplo, fazem esse agrupamento de funções).+notórias são:
  
-Os artigos a seguir explicam por alto como funciona o processo de +  * [[https://gcc.gnu.org/|GCC]] + [[https://www.gnu.org/software/binutils/|Binutils]] (do projeto GNU) 
-compilação:+  * [[https://clang.llvm.org/|Clang]] + [[https://llvm.org/|LLVM]]
  
-  * [[https://pt.wikipedia.org/wiki/Compilador|Compilador]] +Outra um pouco menos conhecida é a do //Tiny C Compiler// (TCC):
-  * [[https://wiki.inf.ufpr.br/computacao/doku.php?id=c:compiladores|Compiladores]] +
-  * [[https://dca.fee.unicamp.br/cursos/EA876/apostila/HTML/node37.html|Compiladores]] +
-  * //[[https://www.cs.man.ac.uk/~pjj/farrell/compmain.html|Compiler Basics]]// (inglês)+
  
-Existem vários compiladores C, alguns mais conhecidos e populares, +  * [[https://bellard.org/tcc/|TCC]]
-outros menos. Você não precisa conhecer todos eles agora (e aliás, +
-dificilmente em algum momento vai precisar conhecer //todos//), mas é +
-importante compreender ao menos um pouco essa variedade e quais são os +
-pontos fortes e fracos de ao menos alguns deles.+
  
-A seguir você encontra uma lista contemplando e categorizando alguns +E ainda outra é a do //Simple C Compiler// (SCC):
-compiladores C:+
  
-  * //[[https://en.wikipedia.org/wiki/List_of_compilers#C_compilers|C compilers]]// (inglês) +  * [[https://www.simple-cc.org/|SCC]]
- +
-Dois compiladores de grande destaque são o [[https://gcc.gnu.org/|GCC]], +
-do projeto GNU, e o [[https://clang.llvm.org/|Clang]], que faz parte da +
-infraestrutura de compilação [[https://llvm.org/|LLVM]]. +
-Conhecer ao menos esses dois já será suficiente para compreender as +
-funções centrais desse tipo de ferramenta.+
  
 === Pré-processamento === === Pré-processamento ===
Linha 250: Linha 240:
  
   * [[https://pt.wikipedia.org/wiki/Pr%C3%A9-processador|Pré-processador]]   * [[https://pt.wikipedia.org/wiki/Pr%C3%A9-processador|Pré-processador]]
 +  * [[https://wiki.inf.ufpr.br/maziero/doku.php?id=c:o_preprocessador_c|O preprocessador C]]
 +  * [[https://dca.fee.unicamp.br/cursos/EA876/apostila/HTML/node150.html|O pré-processador C]]
 +  * [[https://www.ime.usp.br/~pf/algoritmos/apend/preprocessor.html|Pré-processamento]]
   * //[[https://en.wikipedia.org/wiki/C_preprocessor|C preprocessor]]// (inglês)   * //[[https://en.wikipedia.org/wiki/C_preprocessor|C preprocessor]]// (inglês)
  
Linha 262: Linha 255:
   * [[http://mcpp.sourceforge.net|mcpp]]   * [[http://mcpp.sourceforge.net|mcpp]]
   * [[https://github.com/lpsantil/ucpp|ucpp]]   * [[https://github.com/lpsantil/ucpp|ucpp]]
 +  * [[https://www.simple-cc.org/|SCC]] (pré-processador [[https://git.simple-cc.org/scc/file/src/cmd/scc-cc/cc1/cpp.c.html|embutido]] no compilador ''scc-cc'')
  
 === Compilação === === Compilação ===
Linha 272: Linha 266:
 binário compatível com a arquitetura de processamento utilizada. binário compatível com a arquitetura de processamento utilizada.
  
-Recapitulando, C é linguagem portável, assembly não. Cada arquitetura+Recapitulando, C é linguagem portável, Assembly não. Cada arquitetura
 de processamento utiliza sua própria linguagem de montagem, e isso é de processamento utiliza sua própria linguagem de montagem, e isso é
 um dos principais fatores que diferencia C de Assembly. Um programa em um dos principais fatores que diferencia C de Assembly. Um programa em
Linha 280: Linha 274:
 O compilador se encarregará das seguintes operações: O compilador se encarregará das seguintes operações:
  
-  * Análise léxica+  * //Análise léxica//: Fragmenta o código em símbolos, remove partes não essenciais para análises posteriores.
  
-Separa o código em pequenos fragmentos que podem ser analisados +  * //Análise sintática//: Verifica aderência do programa à gramática da linguagem.
-idividulamente, removendo partes não essenciais (espaços e comentários) +
-para as etapas posteriores.+
  
-  * Análise sintática+  * //Análise semântica//: Valida o sentido do programa, como uso correto de tipos e operações e existência de variáveis quando requisitadas.
  
-Verifica a correção do código quanto à gramática da linguagem, isto é, +  * //Geração de código intermediário//: Alguns compiladores, por razões de desempenho e/ou portabilidade usam uma representação intermediária do código, cuja interpretação por uma máquina virtual resultará no código de montagem da arquitetura alvo.
-o respeito às regras formalmente estabelecidas para a escrita de código C.+
  
-  * Análise semântica+  * //Otimização//: Otimizações podem ocorrer ao longo de etapas anteriores, mas a maior parte só é possível após a conversão para uma representação intermediária, com o uso de uma análise heurística sobre o código gerado.
  
-Nessa etapa, o compilador verifica se o código C "faz sentido", isto é, +  * //Geração de código de montagem//: emitir o código //assembly// específico da arquitetura alvo.
-se para além do respeito às regras formais, o significado está correto.+
  
-Isto se aplica aos tipos usados, por exemplo, que podem fazer sentido +Enfim, depois de todo esse processo, temos o código Assembly gerado. 
-em alguns tipos de operação mas não em outros, assim como própria +Agora é possível converter esse código para o binário que a máquina 
-verificação pela existência das variáveis (isto é, se elas foram +será capaz de processar.
-declaradas no escopo utilizado e se possuem valor no momento da +
-utilização).+
  
-  * Geração de código intermediário+Os artigos a seguir falam um pouco mais sobre como funciona esse 
 +processo de compilação:
  
-Alguns compiladores traduzem o código C diretamente para linguagem de +  * [[https://pt.wikipedia.org/wiki/Compilador|Compilador]] 
-montagem. Outros geram uma representação intermediária, que pode ser +  * [[https://wiki.inf.ufpr.br/computacao/doku.php?id=c:compiladores|Compiladores]] 
-executada em uma máquina virtual, ou seja, uma representação composta +  * [[https://dca.fee.unicamp.br/cursos/EA876/apostila/HTML/node37.html|Compiladores]] 
-por instruções aceitas por uma máquina virtual.+  * //[[https://www.cs.man.ac.uk/~pjj/farrell/compmain.html|Compiler Basics]]// (inglês)
  
-Embora essa etapa não seja obrigatória, ela facilita não apenas a +Existem vários compiladores C, alguns mais conhecidos e populares, 
-implementação de otimizações para o código gerado, como também pode +outros menos. Você não precisa conhecer todos eles agora (e aliás, 
-reaproveitar as otimizações para diferentes linguagens de programação. +dificilmente em algum momento vai precisar conhecer //todos//), mas é 
-Ou seja, uma vez que a linguagem de origem for convertida para essa +importante compreender ao menos um pouco essa variedade e quais são os 
-representação intermediária, o programa poderá aproveitar todas as +pontos fortes e fracos de ao menos alguns deles.
-otimizações que essa máquina virtual oferecer.+
  
-  * Otimização+A seguir você encontra uma lista contemplando e categorizando alguns 
 +compiladores C:
  
-O código original pode conter diversas ineficiências que a olho nu +  * //[[https://en.wikipedia.org/wiki/List_of_compilers#C_compilers|C compilers]]// (inglês)
-podem ser difíceis de detectar. Importante destacar que a conversão +
-para a representação intermediárias não elimina essas ineficiências, +
-apenas facilita a sua detecção e correção.+
  
-Portanto, nesta etapa o compilador aplica uma série de heurísticas +Dois compiladores de grande destaque são:
-para detectar trechos de código não alcançável ou redundantes, +
-conversão de expressões equivalentes (porém mais eficientes), dentre +
-outras medidas que tornarão o código resultante mais eficiente.+
  
-Ainda que não seja possível garantir uma eficiência total por meio +  * [[https://gcc.gnu.org/|GCC]] (do projeto GNU) 
-dessas heurísticas, elas tendem a resultar em um código mais eficiente +  * [[https://clang.llvm.org/|Clang]] (relacionado à infraestrutura de compilação [[https://llvm.org/|LLVM]])
-que o original.+
  
-Quando não se usa uma representação intermediária, a quantidade de +Conhecer ao menos esses dois já será suficiente para compreender as 
-otimizações possíveis é bastante reduzida.+funções centrais desse tipo de ferramenta.
  
-Enfim, depois de todo esse processo, temos o código Assembly gerado. +A propósito, estes dois exemplos (GCC e Clang) usam uma representação 
-Agora é possível converter esse código para o binário que a máquina +intermediária para, por um lado, ampliar as linguagens suportadas 
-será capaz de processar.+(já que diferentes linguagens, além de C podem ter seu código convertido 
 +para a representação intermediária) como também ampliar as arquiteturas 
 +suportadas (isto é, converter essa representação para diferentes 
 +linguagens de montagem, de arquiteturas alvo). 
 + 
 +Além do ganho na portabilidade, essa estratégia amplia também as 
 +possibilidades de otimização para ganho de desempenho, por análises 
 +heurísticas que não seriam possíveis lendo apenas a árvore semântica. 
 + 
 +É comum separar esse tipo de arquitetura em camadas: frontal 
 +(//front-end//), média (//middle-end//) e retaguarda (//back-end//). 
 +Enquanto a parte frontal é responsável por converter o código-fonte 
 +(C neste caso) em uma representação intermediária, a parte do meio 
 +identifica oportunidades de otimizações e as aplica. Por fim, a 
 +retaguarda cuida da conversão do resultado em linguagem de montagem. 
 + 
 +No caso do compilador Clang, é a máquina virtual LLVM que se encarrega 
 +de ler a representação intermediária, fazer as otimizações e gerar 
 +o código de montagem. O GCC já possui internamente seu próprio 
 +//back-end//. 
 + 
 +Uma outra opção de infraestrutura de compilação (entenda-se o 
 +//back-end//) é o QBE: 
 + 
 +  * [[https://c9x.me/compile/|QBE]] 
 + 
 +Diferente do GCC e do LLVM, sua prioridade é a simplicidade 
 +e capacidade de inspecionar e estudar o processo de compilação, 
 +ainda que sob pena de realizar menos otimizações sobre o código. 
 + 
 +Alguns compiladores (mais especificamente, //front-ends//) que 
 +visam gerar código intermediário para o QBE são: 
 + 
 +  * [[https://sr.ht/~mcf/cproc/|cproc]] 
 +  * [[https://www.simple-cc.org/|SCC]] (''scc-cc'') 
 + 
 +Por fim, existem compiladores que não utilizam uma representação 
 +intermediária. Um exemplo interessante é o Tiny C Compiler (TCC): 
 + 
 +  * [[https://bellard.org/tcc/|TCC]] 
 + 
 +Sua principal vantagem é uma compilação mais rápida, ainda que 
 +o programa resultante não tenha o mesmo desempenho que o 
 +equivalente gerado por GCC e Clang, geralmente.
  
 === Montagem === === Montagem ===
 +
 +Diferentemente de um processo de compilação, que dá ênfase à
 +intenção do programador quanto //ao quê// deve ser feito pelo programa,
 +a montagem é um processo mais linear, que enfatiza //como// deve ser
 +feito. Portanto, a montagem é uma tradução mais literal de expressões
 +mnemônicas para equivalentes binários que podem ser compreendidos pelo
 +processador alvo.
 +
 +Um código-fonte C pode passar por várias transformações e ainda assim
 +manter seu sentido original, não importanto para o programador quais
 +otimizações precisaram ser aplicadas, desde que o comportamento se
 +mantenha consistente. Já o código de montagem (//assembly//) é mais
 +diretamente equivalente ao resultado (binário).
 +
 +Embora a estrutura geral da linguagem //assembly// possua semelhanças
 +entre diferentes arquiteturas de processamento, existem diferenças
 +suficientes para que se possa considerar como código não portável.
 +O código //assembly// escrito para uma máquina terá de ser reescrito
 +para outra, se esta utilizar uma arquitetura diferente.
 +
 +Para compreender melhor como ocorre esse processo, você pode ler os
 +seguintes documentos:
 +
 +  * [[https://pt.wikipedia.org/wiki/Assembly|Linguagem assembly]]
 +  * [[https://dca.fee.unicamp.br/cursos/EA876/apostila/HTML/node79.html|Montadores]]
 +  * [[https://pt.wikipedia.org/wiki/Linguagem_de_montagem_x86|Linguagem de montagem x86]]
 +  * [[https://dca.fee.unicamp.br/cursos/EA876/apostila/HTML/node107.html|Assembly do 68000]]
 +
 +Ao compreender o processo de montagem, você já deve ter percebido
 +as principais vantagens em programar em C no lugar de programar
 +diretamente em //Assembly//:
 +
 +  * Por ser uma linguagem de alto nível (ao menos comparado a //Assembly//), C permite maior evidenciação sobre o que o programa deve fazer, isto é, é uma linguagem mais expressiva e intuitiva;
 +  * Por ser uma linguagem portável, não será necessário reescrever o programa para cada arquitetura alvo.
 +
 +Para cada arquitetura de processamento, existem diferentes montadores.
 +Você pode conferir uma lista (não exaustiva) no documento a seguir:
 +
 +  * //[[https://en.wikipedia.org/wiki/List_of_assemblers|Comparison of assemblers]]// (em inglês)
  
 === Ligação === === Ligação ===
Linha 720: Linha 784:
 Perfiladores: Perfiladores:
  
-  * [[https://sourceware.org/binutils/docs-2.42/gprof/index.html|GNU Profiler]] (''gprof'')+  * ''gprof'' (existem diferentes implementações) 
 +    * [[https://www.unix.com/man-page/FreeBSD/1/gprof/|BSD]] (originário do 4.2BSD, presente em sistemas BSDs no geral) 
 +    * [[https://sourceware.org/binutils/docs-2.42/gprof/index.html|GNU]] (uma reimplementação no projeto [[https://www.gnu.org/software/binutils/|GNU Binutils]])
   * [[https://perf.wiki.kernel.org/index.php/Main_Page|Linux Perf]] (''perf'')   * [[https://perf.wiki.kernel.org/index.php/Main_Page|Linux Perf]] (''perf'')
   * [[https://valgrind.org/|Valgrind]]   * [[https://valgrind.org/|Valgrind]]
   * [[https://oprofile.sourceforge.io/news/|OProfile]]   * [[https://oprofile.sourceforge.io/news/|OProfile]]
  
prog/guia-de-estudo-c.1771816328.txt.gz · Última modificação: por hrcerq