web-dev-qa-db-fra.com

Évaluation d'expression non intuitive avec incrémentation

Pour le code suivant

<?php

$a=1;   $b=$a++;              var_dump($b);
$a=1;   $b=$a+$a++;           var_dump($b);
$a=1;   $b=$a+$a+$a++;        var_dump($b);
$a=1;   $b=$a+$a+$a+$a++;     var_dump($b);
$a=1;   $b=$a+$a+$a+$a+$a++;  var_dump($b);

J'ai obtenu ce résultat:

int(1)
int(3)
int(3)
int(4)
int(5)

Je m'attendais à 1,2,3,4,5 plutôt qu'à 1,3,3,4,5. Pourquoi après $a=1; $b=$a+$a++; on obtient $b=3?

PHP 7.1.5-1 + deb.sury.org ~ xenial + 1 (cli) (construit: 11 mai 2017 14:07:52) (NTS)

46
Daniel
$a=1;   $b=$a+$a++;           var_dump($b);            // int(3)

Vous supposiez que l'expression ci-dessus est évaluée de gauche à droite comme suit (variables temporaires $u et $v sont introduits dans l'explication pour plus de clarté):

 $a = 1;
 $u = $a;              //    ($a)   the LHS operand of `+`
 $v = $a;              //  \ ($a++) the RHS operand of `+`
 $a ++;                //  /
 $b = $u + $v;         // 2 (1+1)

Mais il n'y a aucune garantie que les sous-expressions soient évaluées dans un ordre spécifié . La page de documentation des opérateurs PHP indique (l'accent est sur le mien):

La priorité et l'associativité des opérateurs déterminent uniquement la façon dont les expressions sont regroupées, elles ne spécifient pas d'ordre d'évaluation. PHP ne spécifie pas (dans le cas général) dans quel ordre une expression est évaluée et le code qui suppose un ordre d'évaluation spécifique doit être évité, car le le comportement peut changer entre les versions de PHP ou selon le code environnant.

Ce n'est que par hasard que les valeurs calculées par PHP pour les autres expressions correspondent aux valeurs que vous avez supposées. Leurs valeurs peuvent être différentes lorsque le code est exécuté en utilisant une version différente de PHP interprète.

30
axiac

PHP ne spécifie pas (dans le cas général) dans quel ordre une expression est évaluée et le code qui suppose un ordre d'évaluation spécifique doit être évité [..]

http://php.net/manual/en/language.operators.precedence.php

La raison pour laquelle vous obtenez des résultats différents est que parfois l'opérande droit et parfois gauche sont évalués en premier. PHP ne fait aucune garantie quant à l'ordre des opérations, il n'y a donc pas de réponse correcte et cela tombe carrément dans la catégorie des comportements indéfinis .

23
deceze

Selon manuel PHP

La priorité et l'associativité des opérateurs déterminent uniquement la façon dont les expressions sont regroupées, elles ne spécifient pas d'ordre d'évaluation. PHP ne spécifie pas (dans le cas général) dans quel ordre une expression est évaluée et le code qui suppose un ordre d'évaluation spécifique doit être évité, car le comportement peut changer entre les versions de PHP ou selon le code environnant.

<?php
$a = 1;
echo $a + $a++; // may print either 2 or 3

$i = 1;
$array[$i] = $i++; // may set either index 1 or 2
?>

La chose étrange est que je m'attendais à ce que les autres lignes comme $b=$a+$a+$a++; suivez le même schéma, mais il ne semble pas.

10
Salketer