2016-10-21 1 views
1

je le code C suivant:Problème de sortie dans les macros?

#include <stdio.h> 

int x = 2; 
int f (int z) { int temp = x; x += 2*z; return temp; } 

#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) /* side effects may cause error */ 
int MIN_fix(X,Y) { if (X < Y) return X; else return Y; } 

int main() { 
unsigned char b = 0x3, c = 0x1; 
printf("result> %d, %d\n", MIN(b+c, f(3)), MIN_fix(b+c, f(3))); 
} 

pourquoi ai-je obtenir "résultat> 4, 2" devrait-il être 8 au lieu de 4?

+4

Avez-vous remarqué le commentaire '/ * Les effets secondaires peuvent causer des erreurs */'? – kdopen

+1

En outre, votre programme a un comportement indéfini car les évaluations des deuxième et troisième arguments de votre appel 'printf' ont tous deux des effets secondaires sur la variable' x', et ceux-ci ne sont pas séquencés les uns par rapport aux autres. –

+0

Voir http://stackoverflow.com/questions/376278/parameter-evaluation-order-before-a-function-calling-in-c Probablement un doublon – kdopen

Répondre

0

Comme cela n'a pas été downvoted ou fermé en double, je vais essayer de vous expliquer

Regardons votre printf appel:

printf("result> %d, %d\n", MIN(b+c, f(3)), MIN_fix(b+c, f(3))); 

Maintenant b+c est effectivement une valeur constante (4), de sorte que cela se transforme en

printf("result> %d, %d\n", MIN(4, f(3)), MIN_fix(4, f(3))); 

Si nous élargissons la macro MIN invokation, et supprimer parens inutiles, nous obtenons les followi ng

printf("result> %d, %d\n", 4 < f(3)? 4 : f(3), MIN_fix(4, f(3))); 

Nous avons donc 3 appels à f(3) dans cette ligne de code. Les trois premiers appels à cette fonction renvoient respectivement 2, 8 et 14. Mais il n'y a aucune garantie dans quel ordre ces appels seront évalués.

Laissons f1 = 2, f2 = 8 et f3 = 14. Votre printf pourrait être l'un des suivants avec leur sortie dans le commentaire

printf(..., 4<f1?4:f2, MIN_fix(4,f3)); // 8, 4 
printf(..., 4<f1?4:f3, MIN_fix(4,f2)); // 14, 4 
printf(..., 4<f2?4:f1, MIN_fix(4,f3)); // 4, 4 
printf(..., 4<f2?4:f3, MIN_fix(4,f1)); // 4, 2 
printf(..., 4<f3?4:f1, MIN_fix(4,f3)); // 4, 4 
printf(..., 4<f3?4:f2, MIN_fix(4,f1)); // 4, 2 

Tout des sorties sont valides - parce que vous avez un comportement non défini