Comme d'autres l'a déjà dit, l'ordre dans lequel les arguments de la fonction sont évalués n'est pas spécifié, et il n'y a pas de point de séquence entre les évaluer. Parce que vous changez pa
par la suite en passant chaque argument, vous ne changez et ne lisez pa
deux fois entre deux séquence de points. C'est en fait un comportement indéfini. J'ai trouvé une très belle explication dans le manuel de GCC, qui, je pense, pourrait être utile:
Le C et le C++ normes définit l'ordre dans lequel les expressions dans un programme C/C++ sont évaluées en fonction de la séquence de points, qui représentent un partiel de la commande entre l'exécution de certaines parties du programme: nombre de personnes exécutées avant la séquence de point, et ceux qui sont exécutés d'après elle. Ceux-ci se produisent après l'évaluation d'une expression complète (qui n'est pas partie d'une expression plus grande), et après l'évaluation du premier opérande de l'un &&, ||, ? : ou , (virgule) de l'opérateur, avant qu'une fonction est appelée (mais après l'évaluation de son argumentation et l'expression désignant la fonction appelée), et dans certains autres endroits. Autres que ce qui est exprimé par la séquence de point de règles, l'ordre d'évaluation des sous-expressions d'une expression n'est pas spécifié. Toutes ces règles décrivent seulement un ordre partiel plutôt qu'un total de la commande, puisque, par exemple, si les deux fonctions sont appelées dans une expression sans point de séquence entre eux, l'ordre dans lequel les fonctions sont appelées n'est pas spécifié. Toutefois, le comité de normalisation ont statué que les appels de fonction ne se chevauchent pas.
Il n'est pas spécifié lors de la entre la séquence des points de modifications apportées aux valeurs des objets prennent effet. Les programmes dont le comportement dépend de cette avoir un comportement indéfini; le C et le C++ normes précisent que "Entre le précédent et suivant de la séquence de point d'un objet doit avoir sa valeur stockée modifié plus d'une fois par l'évaluation d'une expression. En outre, l'état de la valeur est en lecture seule pour déterminer la valeur à stocker.". Si un programme ne respecte pas ces règles, les résultats sur n'importe quel particulier de mise en œuvre sont tout à fait imprévisible.
Des exemples de code avec un comportement indéfini sont a = a++;, a[n] = b[n++] et a[i++] = i;. Certains des cas les plus complexes ne sont pas diagnostiqués par cette option, et il peut donner occasionnellement un résultat faux positif, mais en général, il a été trouvé assez efficace pour détecter ce genre de problème dans les programmes.
La norme est rédigée de prêter à confusion, donc il y a un débat sur le sens précis de la séquence de point de règles en cas subtils. Des liens vers des discussions du problème, y compris des propositions de définitions formelles, peut être trouvé sur la GCC lectures de la page, à http://gcc.gnu.org/readings.html.