Programmation C++/Le préprocesseur
Avant de compiler le programme, il est possible d'effectuer certaines modifications sur le code source. Le programme effectuant ces modifications s'appelle le préprocesseur.
Les commandes destinées au préprocesseur commencent toutes par # en début de ligne.
Inclusion de fichiers.
Pour inclure un fichier à un certain endroit dans le fichier source, on écrit :
 #include ""nom_du_fichier"
Le contenu du fichier nom_du_fichier est alors inséré dans le fichier source.
Le nom du fichier peut être écrit entre guillemets codice_1 ou entre chevrons codice_2. Dans le premier cas, cela signifie que le fichier se trouve dans le même dossier que le fichier source, tandis que dans le deuxième cas, il s'agit d'un fichier se situant dans un endroit différent (ce fichier pouvant être fournit par le compilateur ou une librairie externe par exemple).
Exemple : 
Le fichier C++ standard iostream est inclus à cet endroit-là dans le code. Il contient la définition de certains objets standards notamment cin et cout.
#define, #undef.
La directive codice_3 permet de remplacer toutes les occurrences d'un certain mot par un autre. Par exemple :
Sur cet exemple toutes les occurrences de N seront remplacées par codice_4. Cela est parfois utilisé pour définir des constantes. On préférera toutefois utiliser le mot-clé codice_5.
On peut très bien ne pas fixer de valeur et écrire :
La variable de compilation codice_6 est ici définie. Combiné à codice_7, on pourra compiler ou non certaines parties du code à certains endroits du programme.
De la même façon que l'on peut définir une variable, on peut arrêter une définition en utilisant codice_8. Son utilisation est rare, mais peut servir à ne plus définir une variable de compilation. Par exemple:
#ifdef, #ifndef, #if, #endif et #else.
Présentation.
Toutes ces directives permettent la compilation conditionnelle.
C'est-à-dire que la partie du code comprise entre la directive conditionnelle (codice_7, codice_10 ou codice_11) et la fin du bloc signalée par la directive codice_12 n'est compilée que si la condition est remplie.
Il faut noter que les directives #ifdef et #ifndef, bien que très largement utilisées, sont considérées comme dépréciées ("deprecated"). On préférera donc la syntaxe :
codice_24 à codice_25 et
codice_26 à codice_27.
Il ne faut pas abuser de ces directives et elles sont surtout utilisées :
Exemples.
Exemple 1.
using namespace std;
int main() 
 cout « "BONJOUR";
 cout « "HELLO";
 return 0;
Dans ce programme, il suffit d'effacer codice_29 et de recompiler le programme pour passer d'une version française à une version anglaise. Ceci pourrait être utile si le programme comporte 10 000 lignes (ce qui est faible pour un programme réel). Bien évidemment, il existe bien d'autres façons de gérer le multilinguisme en C++.
Exemple 2.
Cet exemple montre l'utilisation d'expression dans les définitions de valeurs, et les précautions à prendre pour les expressions.
// Définir la taille d'un tableau contenant le prix :
// - de 5 variétés d'orange
// - de 3 variétés de pommes
double prix_fruits[N_TOTAL_FRUITS];
 // ... plus de 7 variétés de fruits
 // ... moins de 7 ou égale à 7 variétés de fruits
cout « "Total de fruits : " « (N_TOTAL_FRUITS) « endl;
// 8
cout « "Double total de fruits : " « (N_TOTAL_FRUITS * 2) « endl;
// <!> 11 au lieu de 16 car l'opérateur * est prioritaire sur +
// dans l'expression étendue 5 + 3 * 2
// --> Utilisez des parenthèses :
// - autour du nom de la macro
cout « "Double total de fruits : " « ((N_TOTAL_FRUITS) * 2) « endl;
// 16
// - mieux : dans la définition
cout « "Double total de fruits : " « (N_TOTAL_FRUITS_MIEUX * 2) « endl;
// 16
Exemple 3.
Fichier toto.h
... écrire ici les prototypes ...
Le problème : 
Imaginons qu'un fichier header toto.h contienne le prototype d'une certaine classe ou d'une fonction. Imaginons que le programme contiennent 3 autres fichiers headers nommés A.h, B.h et C.h qui ont tous les 3 besoin des prototypes inclus dans toto.h, ces 3 fichiers vont commencer par "#include"toto.h"". Imaginons également que C.h a besoin des prototypes inclus dans A.h et B.h. C.h va donc commence par "#include"A.h"" et "#include"B.h"". Le problème est que le fichier "toto.h" va être inclus plusieurs fois. Le compilateur va alors refuser de compiler le programme en indiquant que plusieurs prototypes d'une même fonction sont inclus.
Solution : 
Pour résoudre l'inclusion multiple de fichier headers (inévitable), on va faire commencer le fichier header par "#ifndef TOTO_H "et il se termine par "#endif". Si la variable de compilation "TOTO_H" n'est pas définie, alors le header sera inclus, sinon, il sera tout simplement vide. Juste après "#ifndef TOTO_H", nous allons écrire #define "TOTO_H" définissant justement cette variable de compilation "TOTO_H".
La première fois que le header sera inclus, "TOTO_H" n'est pas défini, le header normal sera donc inclus. "#define TOTO_H" définira alors la variable de compilation "TOTO_H". La deuxième fois que ce même header sera inclus, et les fois suivantes, "TOTO_H" sera défini et par conséquent, le header sera vide. les prototypes n'auront donc été inclus qu'une seule fois. Le tour est joué. Il faut donc faire commencer systèmatiquement (c'est tout du moins conseillé) tous les fichiers header par les 2 lignes "#ifndef ..." et "#define ..." et les faire se terminer par "#endif".
Autre solution.
Toutefois, il existe une autre solution au problème précédent en utilisant la directive suivante en début de fichier codice_30 :
Cette directive indique au compilateur d'ignorer le fichier s'il a déjà été "visité", et ne fonctionne qu'avec certains compilateurs :
Les macros.
Présentation.
Les macros sont des codice_3 particulier parce qu'ils contiennent des paramètres. Ainsi si vous écrivez :
Alors vous pouvez écrire codice_32 et le préprocesseur modifiera cette ligne et la transformera en codice_33. Il y aura substitution de codice_34 par codice_35. Il ne faut pas abuser des macros et très souvent l'utilisation de fonctions, notamment les fonctions inline, est préférable.
Exemple.
using namespace std;
int main() 
 AFFICHER("BONJOUR");
 return 0;
Bonnes pratiques.
Afin d'utiliser correctement les macros, il est préférable de les afficher clairement et de les rendre suffisamment flexible à différentes utilisations.
Si la macros est constituée de plusieurs instructions séparés par des codice_36, il est préférable d'écrire la macro sur plusieurs lignes afin d'accroître sa lisibilité. Pour indiquer à une macro que sa définition continue sur la ligne suivante, il suffit d'indiquer un antislash ('\') en dernier caractère le la ligne.
 cout « x; \
 cout « endl;
L'utilisation la plus courante des macros est de ne pas mettre de codice_36 à la fin de celle-ci, mais de le mettre dans le code, là où elle est utilisée. En effet, on peut prévoir qu'une macro soit utilisable en tant qu'instruction simple, ou en tant que condition ou paramètre de fonction où l'on ne doit pas mettre de codice_36. Pour les macros qui ne retournent rien (comme la macro AFFICHER dans l'exemple précédent), le placement du codice_36 n'est pas un problème car elles ne retournent rien et ne seront jamais utilisées dans une condition ou un appel de fonction.
using namespace std;
int main() 
 int valeur = DIVISER(5, 3);
 if (DIVISER(8, 2) == 4)
 cout « DIVISER(1.0, 5.0) « endl;
 return 0;
Il est fortement conseillé de toujours utiliser un paramètre de macro avec des parenthèses autour. Si l'on reprend l'exemple précédent sans parenthèses :
using namespace std;
int main() 
 int valeur = DIVISER(5, 3);
 if (DIVISER(4 + 4, 2) == 4)
 cout « DIVISER(1.0, 5.0) « endl;
 return 0;
Ici, le résultat obtenu n'est pas forcement celui désiré. codice_40 sera traduit après la précompilation par codice_41. Ceci donne pour valeur 4 + 2, soit 6. Ajouter un maximum de parenthèses permet de s'assurer de la validité de la macro sous plusieurs utilisations différentes. Ainsi, dans l'exemple précédent, une utilisation de parenthèses dans la macro (codice_42), aurait traduit codice_40 en codice_44. Ceci aurait donné comme valeur 8 / 2 = 4, la valeur attendue.