不直观的递增表达式求值

Unintuitive expression evaluation with incrementation

对于下面的代码

<?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);

我得到了这个结果:

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

我预计是 1,2,3,4,5 而不是 1,3,3,4,5。为什么在$a=1; $b=$a+$a++;之后我们得到$b=3

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

PHP does not (in the general case) specify in which order an expression is evaluated and code that assumes a specific order of evaluation should be avoided [..]

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

您得到不同结果的原因是有时先计算右操作数,有时先计算左操作数。 PHP 不保证操作顺序,所以没有正确答案,这完全属于 undefined behaviour.

的范畴

根据PHP manual

Operator precedence and associativity only determine how expressions are grouped, they do not specify an order of evaluation. PHP does not (in the general case) specify in which order an expression is evaluated and code that assumes a specific order of evaluation should be avoided, because the behavior can change between versions of PHP or depending on the surrounding code.

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

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

奇怪的是,我本以为 $b=$a+$a+$a++; 等其他行会遵循相同的模式,但似乎并非如此。

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

假设上面的表达式从左到右计算如下(为了清楚起见,在解释中引入了临时变量$u$v ):

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

但是不能保证子表达式按指定的顺序求值PHP operators 的文档页面指出(重点是我的):

Operator precedence and associativity only determine how expressions are grouped, they do not specify an order of evaluation. PHP does not (in the general case) specify in which order an expression is evaluated and code that assumes a specific order of evaluation should be avoided, because the behavior can change between versions of PHP or depending on the surrounding code.

PHP 为其他表达式计算的值只是碰巧与您假设的值相匹配。当使用不同版本的 PHP 解释器执行代码时,它们的值可能不同。