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.
Mis à jour le 24 septembre 2026
- 1print("Hello")
- 2total = 2 + 3
- 3print(total)
- 4print("Done")
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 :
- Analyse lexicale. Le texte est découpé en tokens, les « mots » du langage : le nom
total, l'opérateur=, le nomprice, l'opérateur*, le nombre3. Les espaces et les commentaires disparaissent à cette étape. - Analyse syntaxique. Les tokens sont organisés en un arbre syntaxique qui enregistre la structure : une affectation dont la valeur est une multiplication de
pricepar3. Le code qui enfreint la grammaire du langage s'arrête ici avec une erreur de syntaxe. - Analyse sémantique. Le compilateur vérifie le sens :
priceest-il déclaré, les types sont-ils compatibles, la fonction appelée existe-t-elle. - 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 * 2peut devenir une seule instruction de décalage, et le code qui ne peut jamais s'exécuter est supprimé. - 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
| Compilateur | Lit | Produit |
|---|---|---|
| GCC, Clang | C, C++ | Du code machine pour x86-64, ARM et d'autres |
| MSVC (Microsoft Visual C++) | C, C++ | Des exécutables Windows (.exe, .dll) |
javac | Java | Du bytecode JVM (fichiers .class) |
rustc | Rust | Du code machine |
go build | Go | Un seul fichier exécutable |
tsc | TypeScript | Du 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
.pycdes 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é.