Qu’est-ce que l’évaluation des arguments?

Herbert Schildt dit:

Dans certaines situations, la fonction réelle doit être utilisée à la place de la macro de type fonction, par exemple: où la taille du code doit être minimisée ou lorsqu’un argument ne doit pas être évalué plus d’une fois.

Que veut-il dire par “un argument ne doit pas être évalué plus d’une fois?”

Prenons une macro pour calculer le maximum de deux valeurs:

#define MAX(a, b) ((a) < (b) ? (a) : (b)) 

Ensuite, nous l'utilisons comme ceci:

 int x = 5; int y = 10; int max = MAX(x++, y++); 

Ensuite, la macro est étendue à

 int max = ((x++) < (y++) ? (x++) : (y++)); 

Comme vous pouvez le constater, l'opération d'incrémentation sur x ou y se produira deux fois , et non ce qui se produirait si vous aviez une fonction dans laquelle chaque argument passé est évalué une seule fois.


Un autre point important est l'utilisation des parenthèses dans la macro. Prenons une autre macro simple:

 #define MUL(a, b) a * b 

Maintenant, si vous appelez la macro en tant que

 int sum = MUL(x + 3, y - 2); 

alors l'expansion devient

 int sum = x + 3 * y - 2; 

Qui, en raison de la priorité de l'opérateur, est égal à

 int sum = x + (3 * y) - 2; 

Souvent pas tout à fait ce à quoi on s'attendait, si on s'attend à (x + 3) * (y - 2) .

Ce problème est aussi "résolu" en utilisant des fonctions.

Parfois, les arguments ont des effets secondaires .

Par exemple, la valeur de i++ est i , mais i est augmentée de 1. Par conséquent, la valeur de i++ sera i + 1 .

Dans une macro, les arguments sont évalués à chaque appel, ce qui entraîne les valeurs résultantes. Dans une fonction, les arguments (réels) sont évalués et copiés dans des arguments (formels) à l’intérieur de la fonction, en ignorant les effets secondaires.

Lorsque vous implémentez une fonction, vous ne vous souciez pas des effets secondaires. Cependant, la promotion et le transtypage implicites de type peuvent être sujets à des erreurs.