Historique de la question
Les macros avec paramètres sont une partie importante du préprocesseur C, apparues pour l'insertion rapide de fragments de code répétitifs et pour simplifier le débogage. Elles sont utilisées pour de courtes fonctions, l'inlining ou l'optimisation.
Problème
Les macros ne vérifient pas les types et ne réalisent pas un remplacement complet en dehors d'un simple substitution textuelle. Des erreurs se produisent en raison de l'absence de parenthèses et de la substitution d'expressions avec des effets secondaires.
Solution
Prévoir des parenthèses autour des paramètres et des définitions de macros, éviter les effets secondaires dans les arguments et utiliser des fonctions inline pour des cas plus complexes.
Exemple de code:
#define MAX(a, b) ((a) > (b) ? (a) : (b)) int x = 5, y = 10; int z = MAX(x++, y++); // Appel dangereux !
Caractéristiques clés :
Le macro remplace-t-il toujours complètement le code comme une fonction ?
Non ! Une macro est simplement une substitution textuelle avant la compilation, elle peut se comporter différemment d'une fonction si les arguments sont des expressions avec des effets secondaires.
Peut-on utiliser n'importe quel appel (y compris avec ++, --) comme paramètre d'une macro ?
C'est très dangereux. Les effets secondaires se produiront plusieurs fois si le paramètre apparaît plus d'une fois dans la macro.
Exemple de code:
// Cet appel augmentera x ou y de plus de 1 MAX(x++, y++)
Comment inclure correctement des parenthèses dans les déclarations de macro ?
Encercler à la fois les paramètres et l'expression à l'intérieur de la macro avec des parenthèses, afin d'éviter les erreurs d'associativité lors de l'appel à l'intérieur d'autres expressions.
Une macro a été définie depuis des années dans une entreprise : #define SQUARE(x) xx, et elle était utilisée pour des expressions comme SQUARE(a+1). Des erreurs inattendues survenaient : l'expression se développait comme a+1a+1, ce qui est différent de (a+1)*(a+1).
Avantages :
La macro SQUARE a été écrite avec des parenthèses complètes : #define SQUARE(x) ((x)*(x)). Son utilisation est standardisée et documentée.
Avantages :