Menu
Coddy logo textTech

Qu'est-ce qu'un compilateur ?

Un compilateur est un programme qui traduit le code source écrit dans un langage de programmation en code machine, ou en une autre forme de plus bas niveau comme le bytecode, avant l'exécution du programme. Le programme traduit peut ensuite s'exécuter sans le code source d'origine.

Par Kevin Spektor, Cofondateur et CTO

Mis à jour le 24 septembre 2026

Code source
  1. 1print("Hello")
  2. 2total = 2 + 3
  3. 3print(total)
  4. 4print("Done")
Sortie
Compilations0
Exécutions0

Compile une fois, puis exécute le programme autant de fois que tu veux : le compteur d'exécutions augmente, celui des compilations non. Active la faute de frappe et le compilateur refuse le programme entier, donc rien ne s'affiche.

Enregistre ce programme C sous le nom hello.c :

#include <stdio.h>

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

Tape ensuite gcc hello.c -o hello. Rien de visible ne se passe pendant un instant, puis un nouveau fichier nommé hello apparaît à côté de ton code source. Ce fichier est le résultat du compilateur : du code machine que ton processeur peut exécuter. Supprime hello.c et ./hello fonctionne toujours, parce que tout ce dont le programme a besoin a déjà été traduit.

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

Comment fonctionne un compilateur, étape par étape

Un compilateur lit le code source comme du texte brut et le traite par étapes. Prenons la seule ligne total = price * 3 :

  1. Analyse lexicale. Le texte est découpé en tokens, les « mots » du langage : le nom total, l'opérateur =, le nom price, l'opérateur *, le nombre 3. Les espaces et les commentaires disparaissent à cette étape.
  2. Analyse syntaxique. Les tokens sont organisés en un arbre syntaxique qui enregistre la structure : une affectation dont la valeur est une multiplication de price par 3. Le code qui enfreint la grammaire du langage s'arrête ici avec une erreur de syntaxe.
  3. Analyse sémantique. Le compilateur vérifie le sens : price est-il déclaré, les types sont-ils compatibles, la fonction appelée existe-t-elle.
  4. Optimisation. Le programme est réécrit pour s'exécuter plus vite ou utiliser moins de mémoire sans changer ce qu'il fait. x * 2 peut devenir une seule instruction de décalage, et le code qui ne peut jamais s'exécuter est supprimé.
  5. Génération de code. Le compilateur écrit le résultat pour une cible : du code machine x86-64 ou ARM, ou du bytecode pour une machine virtuelle.

En C et en C++, une dernière étape, l'édition de liens, réunit tes fichiers compilés et le code des bibliothèques (comme printf, de la bibliothèque standard C) en un seul exécutable. gcc lance l'éditeur de liens pour toi, c'est pourquoi tout semble tenir en une commande.

Python fournit les deux premières étapes sous forme de modules standard, tu peux donc les voir travailler sur une vraie entrée :

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)))

C'est à partir de cet arbre que travaille le reste du compilateur. Il ne se soucie plus des espaces ni des retours à la ligne, seulement de la structure : affecter à total le résultat de la multiplication de price par 3.

La compilation : des erreurs trouvées avant l'exécution

Comme un compilateur lit tout le programme avant qu'une seule ligne ne s'exécute, il peut rejeter les erreurs tôt. Dans cet exemple, aucune des trois lignes print contenues dans source ne s'exécute, pas même la première, parce que le compilateur de Python refuse le texte avant le début de l'exécution :

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

Les compilateurs des langages à typage statique détectent plus que la syntaxe. Cette ligne de C, dans un fichier nommé bad.c, est grammaticalement correcte, mais elle range du texte dans une variable entière :

int count = "five";

GCC 14 et les versions suivantes s'arrêtent avec une erreur :

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

La même erreur en Python n'apparaîtrait qu'à l'exécution de cette ligne. La détecter à la compilation est l'une des raisons pour lesquelles les grandes équipes choisissent des langages compilés et à typage statique. Un compilateur ne peut pas tout détecter pour autant : diviser par un nombre qui s'avère valoir zéro, ou lire un fichier qui n'existe pas, échoue toujours à l'exécution.

Exemples de compilateurs

CompilateurLitProduit
GCC, ClangC, C++Du code machine pour x86-64, ARM et d'autres
MSVC (Microsoft Visual C++)C, C++Des exécutables Windows (.exe, .dll)
javacJavaDu bytecode JVM (fichiers .class)
rustcRustDu code machine
go buildGoUn seul fichier exécutable
tscTypeScriptDu JavaScript

Deux lignes montrent que le code machine n'est pas le seul résultat possible. javac produit du bytecode que la machine virtuelle Java exécute, une partie de l'environnement d'exécution Java. tsc transforme TypeScript en JavaScript, un autre langage de haut niveau ; un compilateur qui fait cela est souvent appelé un transpileur.

Le code machine compilé est lié à une famille de processeurs et à un système d'exploitation. Un programme compilé pour Windows sur x86-64 ne s'exécute pas sur un Mac équipé d'une puce Apple de la série M ; tu recompiles le même code source pour chaque cible.

Compilateur ou interpréteur

Un interpréteur exécute directement le code source au lieu de produire un fichier de programme séparé, et c'est ainsi que Python et Ruby sont généralement exécutés. La plupart des outils modernes combinent les deux idées : CPython compile ton fichier en bytecode puis l'interprète, et la JVM comme le moteur V8 de JavaScript compilent en code machine le code souvent utilisé pendant que le programme tourne. Le tableau comparatif complet se trouve sur la page compilateur ou interpréteur.

Idées reçues

  • « Si ça compile, ça marche. » Un compilateur vérifie que le programme est valide, pas qu'il est correct. Les erreurs de logique et les échecs à l'exécution, comme une division par zéro, passent à travers.
  • « Python n'est pas compilé. » CPython compile chaque fichier en bytecode avant de l'exécuter. Les fichiers .pyc des dossiers __pycache__ sont ce bytecode, enregistré pour les modules que ton programme importe afin que la prochaine exécution puisse sauter cette étape.
  • « Un compilateur en ligne est un compilateur. » Les sites qui exécutent ton code dans le navigateur l'envoient à un serveur qui lance toute la chaîne d'outils (compilateur, éditeur de liens et le programme lui-même) et renvoie le résultat. Le compilateur n'en est qu'une pièce.
  • « Le code compilé s'exécute partout. » Il s'exécute sur le processeur et le système d'exploitation pour lesquels il a été construit. La portabilité vient de la recompilation, ou d'une machine virtuelle comme la JVM.

Pour aller plus loin

La documentation C montre un compilateur en usage quotidien : compiler et exécuter du C détaille le prétraitement, la compilation, l'assemblage et l'édition de liens avec de vraies commandes gcc. Pour découvrir l'autre façon d'exécuter du code, lis compilateur ou interpréteur, puis environnement d'exécution pour savoir ce qui entoure un programme une fois lancé. Le cours C est un bon endroit pour pratiquer avec un langage compilé.

Questions fréquentes

Quels sont les composants d'un compilateur ?
On décrit généralement un compilateur en trois parties. La partie frontale (front end) lit le code source, le découpe en tokens, l'analyse pour construire un arbre syntaxique et vérifie les types. La partie intermédiaire optimise une représentation intermédiaire du programme, et la partie finale (back end) génère le code machine ou le bytecode pour le processeur cible.
Comment un compilateur peut-il se compiler lui-même ?
Par l'amorçage (bootstrapping). La première version d'un compilateur est écrite dans un langage existant, ou compilée par un compilateur plus ancien, puis elle sert à compiler la version suivante, écrite dans le nouveau langage lui-même. GCC, par exemple, est écrit surtout en C et en C++ et se compile avec un compilateur C++ existant, souvent une version antérieure de GCC.
Quelle est la différence entre un compilateur et un assembleur ?
Un compilateur traduit un langage de haut niveau comme C ou Rust, où une ligne peut devenir de nombreuses instructions machine. Un assembleur traduit le langage d'assemblage, où chaque ligne correspond presque exactement à une seule instruction machine. Des compilateurs comme GCC produisent souvent d'abord de l'assembleur, qu'ils confient ensuite à un assembleur.
Qu'est-ce qu'un compilateur JIT ?
Un compilateur à la volée (JIT, just-in-time) traduit le code en code machine pendant l'exécution du programme, et non avant. Il observe quelles parties s'exécutent le plus souvent et les compile, si bien qu'un programme qui tourne longtemps devient plus rapide au fil du temps. La JVM, le moteur V8 de JavaScript et PyPy utilisent tous la compilation JIT.
Faut-il installer un compilateur pour apprendre à programmer ?
Pas au début. Les éditeurs dans le navigateur et les playgrounds en ligne exécutent le compilateur ou l'interpréteur sur un serveur à ta place. Quand tu passes sur ta propre machine, C et C++ demandent un compilateur comme GCC ou Clang, Java un JDK, et Python l'interpréteur Python.
Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER