具有递增的非直观表达式评估

时间:2017-09-05 12:11:26

标签: php increment opcode

以下代码

within('h2', text: 'foo') do |h|
   expect(h).to have_content 'bar'
end     

我得到了这个结果:

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

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

  

PHP 7.1.5-1 + deb.sury.org~xenial + 1(cli)(建于2017年5月11日14:07:52)(NTS)

3 个答案:

答案 0 :(得分:30)

$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州的文档页面(重点是我的):

  

运算符优先级和关联性仅确定表达式的分组方式,它们不指定评估顺序。 PHP不会(在一般情况下)指定评估表达式的顺序,并且应该避免采用特定评估顺序的代码,因为行为可以在PHP版本之间更改或取决于周围的代码。

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

答案 1 :(得分:23)

  

PHP没有(在一般情况下)指定评估表达式的顺序,应该避免采用特定评估顺序的代码[...]

     

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

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

答案 2 :(得分:10)

根据PHP manual

  

运算符优先级和关联性仅确定表达式的方式   如果进行分组,则不会指定评估顺序。 PHP没有   (在一般情况下)指定表达式的顺序   评估和代码应该采用特定的评估顺序   要避免,因为行为可以在PHP或版本之间发生变化   取决于周围的代码。

<?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++;这样的其他行遵循相同的模式,但似乎没有。