Cours 1.3. Compilation

Introduction

Les langages de programmation ne s'exécutent pas tous de la même façon, on distingue deux classes majeurs : les langages compilés et les languges interprétés.

Les langages interprétés

Un langage interprété nécessite l'utilisation d'un interpréteur qui va exécuter le code source. L'interpréteur est un programme intermédiaire qui analyse et exécute les lignes (généralement une par une). Les langages interprétés les plus populaires sont : MATLAB, PHP, Python, Java ... Chacun de ces langages nécessite l'installation de l'interpréteur associé pour fonctionner.

Schéma du fonctionnement générale d'un interpréteur

Les langages compilés

Avec les programmes compilés, l'exécution se fait en deux étapes :

  1. Le code source est d'abord transformé en langage machine.
  2. Ensuite le code transformé est directement exécuté dans le processeur

La première étape, la transformation du code source en langage machine est appelée compilation. La sortie de la compilation est un fichier exécutable, typiquement un fichier .exe sous Windows. Voici quelques exemples de languages compilés : C, C++, C#, swift, Pascal...

Schéma du fonctionnement générale d'un compilateur

De manière générale, les langages compilés sont plus performants, car ils sont exécutés directement dans le processeur. Pour avoir un ordre de grandeur, cette page présente une comparaison entre Python et C++. Le même programme dure 15 minutes en Python, contre 30 secondes en C++. Le graphique ci-dessous donne un ordre de grandeur des ratios d'exécution des différents langages. On s'aperçoit que le C est 10 fois plus rapide que PHP 7 et 40 fois plus rapide que le même programme en Python.

Ratio des vitesses d'exécution des différents langages (compilés et interprétés)

La contrepartie est la durée de compilation : si elle est généralement instantannée, elle peut parfois être beaucoup plus longue sur de gros projets. Par exemple la compilation d'un noyau Linux peut durer une dizaine d'heure. Évidemment, si le code source n'est pas modifié, il est inutile de relancer la compilation avant chaque exécution.

Le compilateur

Avant d'exécuter un code C, il est impératif de le compiler grâce à un compilateur. Dans l'exemple Hello world vu précédemment, si vous regardez attentivement la sortie console, vous vous apercevrez que cette commande est exécutée avant l'exécution du programme :

clang-7 -pthread -lm -o main main.c

Le compilateur crée un fichier main qui est exécutable. Ce fichier est exécuté juste après avec la commande ./main. Si vous tapez à nouveau cette commande dans la console, le programme va s'exécuté une seconde fois.

La compilation

Lors de la compilation, le code source est analysé avant d'être converti. Évidemment, le code source doit respecter certaines règles pour être compilable. La première règle à connaitre est que chaque instruction se termine par un point-virgule. Voici les lignes de la fonction principale du programme Hello world :

printf("Hello World\n");
return 0;

Le point-virgule indique au compilateur que l'instruction se termine et que la suivante débute. Cela lui permet d'analyser le code de façon automatique. Si vous omettez un point-virgule, le compilateur ne fera pas la différence entre les deux instructions, pour lui vous aurez écrit quelque chose comme :

printf("Hello World\n")return 0;

printf et return ne seront plus qu'une seule instruction. Certains éditeurs comme Qt Creator affiche une petite flêche pour indiquer la ligne de l'erreur. Il n'est pas rare que le compilateur place la flêche sur la deuxième ligne et non sur celle où le point-virgule est omis, car de son point de vue les deux lignes sont la même instruction.

Pour des raisons de lisibilité, on écrit les programme avec une instruction par ligne. En réalité le compilateur ne regarde pas les sauts de ligne. Les seules séparations qui comptent pour lui sont les points-virgules. Le programme Hello world pourrait s'écrire sur une seule ligne tant que les instructions sont séparées par des points-virgules :

#include <stdio.h> 
int main(void) { printf("Hello World\n"); return 0; }

Ce programme, même s'il fonctionne est illisible. Ce type d'écriture est à banir.

Remarque : la première ligne n'a pas de point-virgule, car ce n'est pas une instruction, mais une directive de compilation. En effet, cette ligne n'est pas destinée à être exécutée. Elle sert à transmettre une information au compilateur. Ici, elle précise au compilateur que ce dernier devra utiliser la bibliothèque stdio.h.

Erreurs de compilation

Au moment de la transformation du code en langage machine, le compilateur analyse le code et détecte d'éventuelles erreurs :

Au moment du déploiement d'une application, l'idéal est de ne pas avoir d'erreurs, ni d'avertissement. Pour les erreurs, c'est impératif. Concernant les avertissements, il ne sont pas toujours corrigés. Mais si vous conserver les problèmes qui y sont liés, vous devez les comprendre et le faire en connaissance de cause.

Quiz

Quelles propositions sont vraies ?

Vérifier Bravo ! Un interpréteur analyse et exécute le code ligne par ligne. Essaie encore ...

À propos des compilateur ...

Vérifier Bravo ! Le compilateur convertir le code en un fichier qui pourra être exécuté dans un second temps. Essaie encore ...

Quel est le problème avec le code ci-dessous ?

int main(void){printf("Drole d'exercice !\n");return 0;}
Vérifier Bravo ! Ce programme est compréhensible par la machine, mais moins par l'homme. Essaie encore ...

Quel est le problème avec le code ci-dessous ?

int main(void) {
  printf("Drole d'exercice !\n")
  return 0
};
Vérifier Bravo ! On mets un point-virgule à la fin des instructions, mais pas des fonctions. Essaie encore ...

Avec le résultat de compilation suivant :

main.c:3:26: error: expected ';' after expression
  printf("Bonjour\n")
Vérifier Bravo ! L'absence de point-virgule génére une erreur qui empèche la compilation. Essaie encore ...

Au moment de la compilation un avertissement apparait :

main.c:5:8: warning: using the result of an assignment as a condition without parentheses
      [-Wparentheses]
  if (i=5) printf ("Hello");
Vérifier Bravo ! Les avertissements n'empèche pas l'exécution du programme, mais il doivent être considérés avec attention. Essaie encore ...

Voir aussi


Dernière mise à jour : 30/09/2021