La compilation séparée
Nous venons de voir comment inclure une bibliothèque avec la pseudo-instruction
#include
et le fichier que nous importons ainsi est en général un fichier avec
l’extension .h
ou .hpp
(spécifique à C++).
Contrairement à Java où nous n’avons qu’un fichier .java
et où nous utilisons
les modificateurs public
, protected
ou private
pour indiquer ce qui est
privé ou public, une bibliothèque C/C++ a besoin de 2 fichiers.
Un fichier .c
ou .cpp
avec l’implémentation et un autre fichier .h
ou .hpp
avec la déclaration des éléments publics.
Les extensions .c
et .h
s’utilisent pour un fichier source en C
et les extensions .cpp
et .hpp
pour un fichier en C++.
Note
Certaines bibliothèques en C++ utilisent aussi l’extension .h
et
parfois même aucune extension, mais dans le contexte de ce cours, nous
utiliserons l’extension .hpp
pour les fichiers en C++.
Illustrons ceci avec un exemple. Supposons que nous souhaitons mettre à disposition une bibliothèque avec une fonction qui calcule le maximum de deux nombres. La fonction ressemblerait à ça :
int max(int a, int b) {
if (a > b) {
return a;
} else {
return b;
}
}
Pour pouvoir importer cette fonction dans un programme, nous écrivons
un fichier .hpp
(par exemple max.hpp
) avec le contenu suivant :
#pragma once
int max(int a, int b);
On appelle ces fichiers des header files
(d’où l’extension .h
) et
ils ne contiennent que les entêtes (ou les interfaces) des procédures.
Notez la directive #pragma once
qui est une pseudo-instruction du préprocesseur.
cette directive permet de s’assurer que le fichier n’est importé qu’une seule fois,
évitant ainsi des erreurs de compilation.
On implémente ensuite la fonction dans un fichier .cpp
(par exemple max.cpp
)
avec le contenu suivant.
#include "max.hpp"
int max(int a, int b) {
if (a > b) {
return a;
} else {
return b;
}
}
Notez que l’implémentation importe sa propre interface (le fichier max.cpp
importe max.hpp
).
Ce n’est pas toujours obligatoire, mais c’est une pratique très courante qui permet au compilateur
de vérifier que l’implémentation correspond bien à l’interface.
Une application se compose souvent de plusieurs fichiers .c
, .cpp
/ .h
.hpp
pour les
bibliothèques locales ainsi qu’un fichier dans lequel est implémentée la méthode int main()
.
Vous pouvez appeler ce fichier comme vous voulez, mais on l’appelle souvent main.c
ou main.cpp
.
La méthode main
sera appelée lorsque vous exécuterez votre programme. Notez que ce fichier
ne s’accompagne pas d’un fichier .h
ou .hpp
, car c’est le programme principal et il
n’est pas importé par d’autres fichiers.
Le C et le C++ sont compatibles jusqu’à un certain point. Une fonction écrite en C
peut être utilisée par un programme en C++ si on lui ajoute le préfixe extern "C"
.
Si vous voulez écrire une bibliothèque utilisable en C comme en C++, la bonne pratique
consiste à implémenter le fichier .h
de la manière suivante :
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
// Declare C functions here
#ifdef __cplusplus
}
#endif
Le préprocesseur ajoute ce qu’il faut si on importe ce fichier depuis C++
et ignore la déclaration extern "C"
supplémentaire si on importe depuis C.