Menu

Compiler du C++ : du code source à un exécutable avec g++

Comment le C++ transforme un source .cpp en exécutable natif : compilez avec g++ (ou clang++/MSVC), lancez le binaire et lisez les erreurs du compilateur quand ça ne va pas.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Compiler, puis exécuter

Maintenant que vous avez un compilateur installé, faire tourner un programme C++ est un cycle en deux étapes. Contrairement à un langage de script, où un interpréteur lit votre fichier ligne par ligne, le C++ compile d'abord votre source en un exécutable natif - un binaire autonome de code machine - puis vous exécutez ce binaire directement. Il n'y a aucun interpréteur entre votre programme et le CPU à l'exécution.

C'est cette séparation qui rend le C++ rapide, et aussi pourquoi une faute de syntaxe vous arrête à la compilation plutôt qu'au milieu d'une exécution. Le compilateur vérifie tout le fichier avant de produire quoi que ce soit.

Vous pouvez exécuter n'importe quel exemple autonome ici même, sur la page - l'éditeur ci-dessous le compile et l'exécute pour vous. Mais il vaut la peine de savoir ce qui se passe sur votre propre machine, car c'est là que vivent les vrais projets.

Le cycle compiler-et-exécuter sur votre machine

Supposons que vous ayez enregistré ceci dans main.cpp :

#include <iostream>
using namespace std;

int main() {
    cout << "Hello from the terminal" << endl;
    return 0;
}

Ouvrez un terminal dans le dossier qui contient le fichier et invoquez le compilateur. Le compilateur le plus courant est g++ (partie de GCC) ; clang++ fonctionne à l'identique pour tout ce qui suit :

g++ main.cpp -o main

Si le code compile sans accroc, g++ n'affiche rien et crée un nouveau fichier à côté de votre source : un exécutable appelé main (ou main.exe sous Windows). Ce binaire, c'est du code machine - pas du texte lisible, et lié à votre système d'exploitation et à votre CPU. Exécutez-le maintenant :

./main
Hello from the terminal

Sous Windows, vous le lanceriez avec main.exe (ou simplement main) depuis le même terminal. Le ./ sous macOS et Linux indique au shell « le programme est juste ici, dans ce dossier, pas quelque part dans le PATH » - une étape que les débutants oublient, avant de se demander pourquoi main répond command not found.

Ce que fait -o (et a.out)

L'option -o nomme la sortie. Si vous l'omettez, g++ compile quand même, mais écrit l'exécutable sous un nom par défaut : a.out sous macOS/Linux, a.exe sous Windows.

g++ main.cpp        # produces a.out, not main
./a.out

Cela piège les gens en permanence : ils compilent, ne voient aucune erreur, lancent ./main et obtiennent No such file or directory - parce que le binaire s'appelle en réalité a.out. Passez toujours -o pour savoir exactement ce que vous exécutez.

Vous compilez une fois par modification du source. Ensuite, l'exécutable est indépendant - vous pouvez lancer ./main cent fois sans recompiler. Vous ne relancez g++ qu'après avoir modifié le fichier .cpp.

Choisir une norme C++

Le C++ a des versions - C++11, C++14, C++17, C++20, C++23 - chacune ajoutant des fonctionnalités au langage. Le hic : votre compilateur choisit une norme par défaut qui peut être plus ancienne que prévu, si bien que du code moderne peut refuser de compiler sans raison apparente. Fixez la norme explicitement avec -std :

g++ -std=c++17 main.cpp -o main
g++ -std=c++20 main.cpp -o main

Voici un code qui utilise une fonctionnalité du C++17 (les structured bindings). Il compile très bien dans l'éditeur, mais sur votre machine il a besoin de -std=c++17 ou plus récent :

Si vous voyez un jour une erreur du type 'structured bindings' only available with '-std=c++17', le correctif n'est pas dans votre code - il s'agit d'ajouter la bonne option -std. Tout au long de ce cours, partez du principe que vous êtes en C++17 ou plus récent.

Activez les avertissements

Un programme C++ peut compiler sans accroc et être quand même faux. Le compilateur, si vous le lui demandez, signalera le code suspect avant qu'il ne vous morde à l'exécution. Ajoutez -Wall -Wextra :

g++ -std=c++17 -Wall -Wextra main.cpp -o main

Considérez ce programme. Il compile sans -Wall, mais il a un vrai bug - lire une variable à laquelle aucune valeur n'a jamais été donnée, ce qui est un comportement indéfini :

#include <iostream>
using namespace std;

int main() {
    int count;                 // never initialized
    cout << count << endl;     // reads garbage - undefined behavior
    return 0;
}

Avec les avertissements activés, le compilateur le signale :

warning: 'count' is used uninitialized [-Wuninitialized]

Prenez l'habitude de compiler avec -Wall -Wextra dès le premier jour. Les avertissements, c'est le compilateur qui vous offre une revue de code gratuite ; les ignorer, c'est ainsi que des bugs subtils survivent. Le correctif ici est simplement int count = 0;.

Lire les erreurs du compilateur

Quand g++ rejette votre code, il indique le fichier, la ligne et ce qui n'a pas marché. Apprendre à lire ces messages, c'est la moitié du chemin pour vous débloquer. Voici le grand classique - un point-virgule manquant :

#include <iostream>
using namespace std;

int main() {
    cout << "Oops"      // no semicolon
    return 0;
}
main.cpp:5:5: error: expected ';' before 'return'
    5 |     return 0;
      |     ^~~~~~

Quelques points à remarquer. L'erreur indique la ligne 5, mais la faute est à la ligne 4 - le compilateur ne se rend compte qu'il manque un point-virgule qu'une fois arrivé au token suivant. Donc, quand une erreur pointe une ligne qui semble correcte, regardez la ligne précédente. main.cpp:5:5, c'est le fichier, la ligne, puis la colonne. Corrigez la seule chose qu'il nomme et recompilez - évitez de deviner au hasard.

Les erreurs de compilation signifient que rien ne s'est encore exécuté. Elles diffèrent des erreurs d'exécution, où votre programme a démarré puis s'est planté. Attraper les fautes à la compilation, avant même que le programme ne tourne, est l'une des plus grandes forces du C++.

Un programme de vérification

Lancez ceci dans l'éditeur, ou enregistrez-le dans main.cpp et faites g++ -std=c++17 -Wall main.cpp -o main puis ./main sur votre propre machine. Si les trois lignes apparaissent, votre chaîne d'outils fonctionne de bout en bout :

Trois choses apparaissent ici, que vous rencontrerez bientôt comme il faut : une variable int, un vector (le tableau redimensionnable du C++) et cout pour l'affichage. Pour l'instant, il suffit que le programme compile et affiche les trois lignes dans l'ordre.

Suivant : la syntaxe du C++

Vous avez compilé et exécuté quelques programmes, mais on a survolé la ponctuation - les lignes #include, les accolades, les points-virgules, int main() et pourquoi chaque ligne a cette allure. La page suivante décortique la syntaxe du C++ morceau par morceau, pour que la structure cesse de ressembler à du remplissage et commence à prendre du sens.

Questions fréquentes

Comment compiler et exécuter un programme C++ ?

Enregistrez votre code dans main.cpp, ouvrez un terminal dans ce dossier et lancez g++ main.cpp -o main pour produire un exécutable. Lancez-le ensuite avec ./main sous macOS/Linux ou main.exe sous Windows. Vous compilez une fois ; vous pouvez exécuter le binaire obtenu autant de fois que vous le voulez.

À quoi sert l'option -o dans g++ ?

-o donne un nom au fichier de sortie. g++ main.cpp -o hello crée un exécutable appelé hello. Sans -o, g++ utilise par défaut a.out (ou a.exe sous Windows) - c'est pourquoi les débutants finissent souvent par exécuter un fichier qu'ils ne savaient pas avoir créé.

Comment compiler du C++ avec une norme précise comme C++17 ou C++20 ?

Passez l'option -std : g++ -std=c++17 main.cpp -o main ou -std=c++20. Sans elle, le compilateur utilise sa propre valeur par défaut, qui peut être plus ancienne que prévu ; ainsi, des fonctionnalités récentes comme les structured bindings ou <ranges> peuvent refuser de compiler tant que vous ne fixez pas explicitement la norme.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER