Menu
Coddy logo textTech

O que é um compilador?

Um compilador é um programa que traduz o código-fonte escrito em uma linguagem de programação para código de máquina, ou para outra forma de nível mais baixo como bytecode, antes de o programa executar. O programa traduzido pode então executar sem o código-fonte original.

Por Kevin Spektor, Cofundador e CTO

Atualizado em 24 de setembro de 2026

Código-fonte
  1. 1print("Hello")
  2. 2total = 2 + 3
  3. 3print(total)
  4. 4print("Done")
Saída
Compilações0
Execuções0

Compile uma vez e depois execute o programa quantas vezes quiser: o contador de execuções sobe, o de compilações não. Ative o erro de digitação e o compilador recusa o programa inteiro, então nada é impresso.

Salve este programa C como hello.c:

#include <stdio.h>

int main(void) {
    int price = 4;
    printf("Total: %d\n", price * 3);
    return 0;
}

Depois digite gcc hello.c -o hello. Por um momento nada visível acontece, e então aparece um novo arquivo chamado hello ao lado do seu código-fonte. Esse arquivo é a saída do compilador: código de máquina que o seu processador consegue executar. Apague hello.c e ./hello continua funcionando, porque tudo de que o programa precisa já foi traduzido.

gcc hello.c -o hello
./hello
Total: 12

Como um compilador funciona, passo a passo

Um compilador lê o código-fonte como texto puro e o processa em etapas. Pegue a linha total = price * 3:

  1. Análise léxica. O texto é dividido em tokens, as "palavras" da linguagem: o nome total, o operador =, o nome price, o operador *, o número 3. Espaços e comentários são descartados aqui.
  2. Análise sintática (parsing). Os tokens são organizados em uma árvore sintática que registra a estrutura: uma atribuição cujo valor é uma multiplicação de price por 3. Um código que quebra a gramática da linguagem para aqui com um erro de sintaxe.
  3. Análise semântica. O compilador verifica o significado: price foi declarada, os tipos são compatíveis, a função chamada existe.
  4. Otimização. O programa é reescrito para executar mais rápido ou usar menos memória sem mudar o que ele faz. x * 2 pode virar uma única instrução de deslocamento, e o código que nunca pode executar é removido.
  5. Geração de código. O compilador grava a saída para um destino: código de máquina x86-64 ou ARM, ou bytecode para uma máquina virtual.

Em C e C++, uma etapa final, a ligação (linking), junta os seus arquivos compilados com o código de bibliotecas (como printf, da biblioteca padrão do C) em um único executável. O gcc executa o linker para você, e por isso parece um só comando.

O Python traz as duas primeiras etapas como módulos padrão, então você pode vê-las funcionando com uma entrada real:

NAME 'total'
OP '='
NAME 'price'
OP '*'
NUMBER '3'
Assign(
  targets=[
    Name(id='total', ctx=Store())],
  value=BinOp(
    left=Name(id='price', ctx=Load()),
    op=Mult(),
    right=Constant(value=3)))

Essa árvore é a base de todo o resto do trabalho do compilador. Ela não se importa mais com espaços ou quebras de linha, só com a estrutura: atribuir a total o resultado de multiplicar price por 3.

Tempo de compilação: erros encontrados antes de o programa executar

Como um compilador lê o programa inteiro antes que qualquer parte dele execute, ele pode rejeitar erros cedo. Neste exemplo nenhuma das três linhas print dentro de source executa, nem mesmo a primeira, porque o compilador do Python recusa o texto antes de a execução começar:

Rejected before running anything:
  '(' was never closed (line 3)

Compiladores de linguagens com tipagem estática pegam mais do que erros de sintaxe. Esta linha de C, em um arquivo chamado bad.c, está gramaticalmente correta, mas guarda texto em uma variável inteira:

int count = "five";

O GCC 14 e versões mais novas param com um erro:

bad.c:4:17: error: initialization of 'int' from 'char *' makes integer from pointer without a cast [-Wint-conversion]

O mesmo erro em Python só apareceria quando essa linha executasse. Pegá-lo em tempo de compilação é um dos motivos pelos quais equipes grandes escolhem linguagens compiladas com tipagem estática. Mas um compilador não consegue pegar tudo: dividir por um número que acaba sendo zero, ou ler um arquivo que não existe, ainda falha em tempo de execução.

Exemplos de compiladores

CompiladorLêGera
GCC, ClangC, C++Código de máquina para x86-64, ARM e outros
MSVC (Microsoft Visual C++)C, C++Executáveis Windows (.exe, .dll)
javacJavaBytecode da JVM (arquivos .class)
rustcRustCódigo de máquina
go buildGoUm único arquivo executável
tscTypeScriptJavaScript

Duas linhas mostram que "código de máquina" não é a única saída possível. O javac gera bytecode que a Máquina Virtual Java executa, parte do ambiente de execução Java. O tsc transforma TypeScript em JavaScript, outra linguagem de alto nível; um compilador que faz isso costuma ser chamado de transpilador.

O código de máquina compilado fica preso a uma família de CPU e a um sistema operacional. Um programa compilado para Windows em x86-64 não executa em um Mac com chip Apple da série M; você compila o mesmo código-fonte de novo para cada destino.

Compilador ou interpretador

Um interpretador executa o código-fonte diretamente, em vez de gerar um arquivo de programa separado, e é assim que Python e Ruby normalmente são executados. A maioria das ferramentas modernas usa as duas ideias: o CPython compila o seu arquivo para bytecode e depois o interpreta, e a JVM e o motor V8 do JavaScript compilam para código de máquina o código usado com frequência enquanto o programa executa. A tabela completa lado a lado está na página compilador vs interpretador.

Equívocos comuns

  • "Se compila, funciona." Um compilador verifica se o programa é válido, não se ele está correto. Erros de lógica e falhas em tempo de execução, como divisão por zero, passam.
  • "Python não é compilado." O CPython compila cada arquivo para bytecode antes de executá-lo. Os arquivos .pyc nas pastas __pycache__ são esse bytecode, salvo para os módulos que o seu programa importa, para que a próxima execução pule essa etapa.
  • "Um compilador online é um compilador." Sites que executam seu código no navegador o enviam a um servidor que roda toda a cadeia de ferramentas (compilador, linker e o próprio programa) e devolve a saída. O compilador é uma peça disso.
  • "Código compilado roda em qualquer lugar." Ele roda na CPU e no sistema operacional para os quais foi gerado. A portabilidade vem de recompilar, ou de uma máquina virtual como a JVM.

Para onde ir agora

A documentação de C mostra um compilador no uso diário: como compilar e executar C passa pelo pré-processamento, compilação, montagem e ligação com comandos gcc reais. Para ver a outra forma de executar código, leia compilador vs interpretador e depois ambiente de execução, sobre o que envolve um programa depois que ele começa. O curso de C é um bom lugar para praticar com uma linguagem compilada.

Perguntas frequentes

Quais são os componentes de um compilador?
Um compilador costuma ser descrito em três partes. O front end lê o código-fonte, divide em tokens, monta uma árvore sintática e verifica os tipos. O middle end otimiza uma forma intermediária do programa, e o back end gera código de máquina ou bytecode para a CPU de destino.
Como um compilador consegue compilar a si mesmo?
Por bootstrapping. A primeira versão de um compilador é escrita em uma linguagem que já existe, ou compilada por um compilador mais antigo, e depois é usada para compilar a versão seguinte, escrita na própria linguagem nova. O GCC, por exemplo, é escrito principalmente em C e C++ e é compilado com um compilador C++ já existente, muitas vezes um GCC anterior.
Qual é a diferença entre compilador e montador (assembler)?
Um compilador traduz uma linguagem de alto nível como C ou Rust, em que uma linha pode virar muitas instruções de máquina. Um montador (assembler) traduz linguagem assembly, em que cada linha corresponde quase uma a uma a uma única instrução de máquina. Compiladores como o GCC muitas vezes geram assembly primeiro e o entregam a um montador.
O que é um compilador JIT?
Um compilador just-in-time (JIT) traduz código para código de máquina enquanto o programa está executando, e não antes. Ele observa quais partes executam com mais frequência e compila essas, então um programa que fica muito tempo rodando vai ficando mais rápido. A JVM, o motor V8 do JavaScript e o PyPy usam compilação JIT.
Preciso instalar um compilador para aprender a programar?
No começo, não. Editores no navegador e playgrounds online executam o compilador ou o interpretador em um servidor para você. Quando você passar para a sua própria máquina, C e C++ precisam de um compilador como GCC ou Clang, Java precisa de um JDK e Python precisa do interpretador Python.
Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR