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/22 23:25] – [Compiladores] link atualizado (estava quebrado) 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 ===
 +
 +Bem, depois que o pré-processamento está concluído, temos apenas código
 +C, porém o objetivo final é ter código de máquina. Como chegar lá? A
 +tradução não é direta (de C para binário). Antes disso, o código C deve
 +ser convertido para a linguagem de montagem (Assembly) específica da
 +máquina alvo, ou seja, uma linguagem de montagem capaz de gerar código
 +binário compatível com a arquitetura de processamento utilizada.
 +
 +Recapitulando, C é linguagem portável, Assembly não. Cada arquitetura
 +de processamento utiliza sua própria linguagem de montagem, e isso é
 +um dos principais fatores que diferencia C de Assembly. Um programa em
 +C pode ser compilado para qualquer arquitetura de processamento, desde
 +que haja um compilador C para aquela arquitetura.
 +
 +O compilador se encarregará das seguintes operações:
 +
 +  * //Análise léxica//: Fragmenta o código em símbolos, remove partes não essenciais para análises posteriores.
 +
 +  * //Análise sintática//: Verifica aderência do programa à gramática da linguagem.
 +
 +  * //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.
 +
 +  * //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.
 +
 +  * //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.
 +
 +  * //Geração de código de montagem//: emitir o código //assembly// específico da arquitetura alvo.
 +
 +Enfim, depois de todo esse processo, temos o código Assembly gerado.
 +Agora é possível converter esse código para o binário que a máquina
 +será capaz de processar.
 +
 +Os artigos a seguir falam um pouco mais sobre como funciona esse
 +processo de compilação:
 +
 +  * [[https://pt.wikipedia.org/wiki/Compilador|Compilador]]
 +  * [[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,
 +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
 +compiladores C:
 +
 +  * //[[https://en.wikipedia.org/wiki/List_of_compilers#C_compilers|C compilers]]// (inglês)
 +
 +Dois compiladores de grande destaque são:
 +
 +  * [[https://gcc.gnu.org/|GCC]] (do projeto GNU)
 +  * [[https://clang.llvm.org/|Clang]] (relacionado à 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.
 +
 +A propósito, estes dois exemplos (GCC e Clang) usam uma representação
 +intermediária para, por um lado, ampliar as linguagens suportadas
 +(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 646: 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.1771802745.txt.gz · Última modificação: por hrcerq