Comportement non défini de l’incrément postfixe ou préfixe dans les appels de fonction en C

J’ai vu sur ce site que l’incrément de préfixe ou l’incrément de postfix dans un appel de fonction peut provoquer un comportement indéfini. Je suis passé par l’un de ceux récemment. Le code source ressemble à ceci:

#include  void call(int,int,int); int main() { int a=10; call(a,a++,++a); printf("****%d %d %d***_\n",a,a++,++a); return 0; } void call(int x,int y,int z) { printf("%d %d %d",x,y,z); } 

La sortie apparaît sous la forme 12 11 12 **** 14 13 14 *** _. Mais, quand a est imprimé en premier dans la fonction, ne devrait-il pas être 10? Pourquoi devient-il 12? Aussi, pourquoi un ++ diminue-t-il de 12 à 11? Quelqu’un peut-il s’il vous plaît bien vouloir expliquer? Je vous remercie.

C’est un comportement indéfini et en tant que tel, il dépend entièrement de l’implémentation du compilateur, dans lequel les opérations suivantes sont effectuées:

  1. soumettre l’argument a
  2. soumettre l’argument a++
  3. soumettre l’argument ++a
  4. incrémenter a pour ++a
  5. incrémenter a pour a++

La seule chose que le compilateur sait est que: 2. doit se produire avant 5. et 4. doit se produire avant 3.

Vous observez:

 ++a; submit argument 2 a++; submit the other arguments 

Votre code d’exemple nous oblige à prendre en compte deux éléments:

  1. L’ordre des arguments de la fonction d’évaluation n’est pas spécifié. Par conséquent, ++a ou a++ est évalué en premier, mais dépend de la mise en œuvre.

  2. La modification de la valeur de plusieurs fois sans sharepoint séquence entre les modifications constitue également un comportement indéfini.

En raison du point 2, vous avez un double comportement indéfini ici (vous le faites deux fois). Notez qu’un comportement indéfini ne signifie pas que rien ne se passe; cela signifie que tout peut arriver.

 call(a,a++,++a); /* UB 1 */ printf("****%d %d %d***_\n",a,a++,++a); /* UB 2 */ 

Les normes C et C ++ n’indiquent pas d’ordre d’évaluation pour les arguments de fonction. Pour être franc, il n’est pas incorrect pour un compilateur d’évaluer les parameters de droite à gauche ou de gauche à droite.

La meilleure réponse est de restr loin de ce type de «comportement indéfini»; car cela peut conduire à des problèmes de portabilité subtils.

Il n’est pas nécessaire d’être égal à quoi que ce soit ; c’est ce que l’on entend par comportement indéfini. Il appartient entièrement au compilateur d’évaluer les arguments à call et à printf dans l’ordre de son choix, car le langage ne spécifie pas l’ ordre dans lequel ils doivent être évalués.