Historique de la question :
Les macros proviennent du langage C comme un moyen puissant d'automatiser des sections de code répétitives au stade de la prétraitement. Dans C++, leur utilisation a apporté de la flexibilité, mais a aussi entraîné de nombreux dangers cachés à cause de l'absence de vérification des types et du fonctionnement non évident du préprocesseur.
Problème :
Les principaux risques d'utilisation des macros :
Solution :
Dans les standards modernes de C++, il est recommandé d'utiliser des fonctions inline, des templates, des constexpr, des enum class, ainsi que des variables constexpr au lieu de macros.
Exemple de code :
// Mauvais : #define MAX(a, b) ((a) > (b) ? (a) : (b)) // Bon : template<typename T> constexpr T max(T a, T b) { return a > b ? a : b; }
Caractéristiques clés :
Une macro peut-elle être plus dangereuse qu'une fonction inline ?
Oui. Une macro ne suit pas les règles de syntaxe et de types. Un résultat inattendu peut survenir lors du passage de paramètres avec des effets secondaires.
#define SQUARE(x) ((x) * (x')) int y = 5; int z = SQUARE(y++); // y s'incrémente deux fois !
#include est-elle aussi une macro ?
Non, #include est une directive de préprocesseur, mais l'utilisation de macros et de includes est liée : on peut changer la liste des fichiers inclus via une macro (extrêmement déconseillé).
Peut-on déboguer une macro comme une fonction ordinaire ?
Non, le débogueur dévoile la macro et montre le texte déjà substitué, il n'y a pas d'entités nommées distinctes.
Dans un ancien code, de nombreux macros de calcul ont été définis avec des effets (par exemple, incrément), ce qui a entraîné des bugs difficiles à détecter lors de l'utilisation de nouvelles fonctionnalités.
Avantages :
Inconvénients :
Lors du refactoring, les macros ont été remplacées par des fonctions templates et constexpr, et enum class a été utilisé à la place des macros drapeaux.
Avantages :
Inconvénients :