web-dev-qa-db-ja.com

増分による直感的でない式評価

次のコードの場合

<?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,3,3,4,5ではなく1,2,3,4,5を期待していました。なぜ$a=1; $b=$a+$a++; 私達は手に入れました $b=3

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

46
Daniel
$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演算子 のドキュメントページ(強調は私のものです):

演算子の優先順位と結合性は、式のグループ化方法のみを決定し、評価の順序を指定しません。 PHPは(一般的な場合)式が評価される順序を指定せず、特定の評価順序を前提とするコードは避ける必要があります。 PHPまたは周囲のコードによって異なります。

偶然にPHPで計算された他の式の値は、想定した値と一致します。異なるバージョンのPHP通訳。

30
axiac

PHPは(一般的な場合)式が評価される順序を指定せず、評価の特定の順序を前提とするコードは避けるべきです[..]

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

異なる結果が得られる理由は、右側のオペランドと左側のオペランドが最初に評価される場合があるためです。 PHPは操作の順序について何も保証しないため、正しい答えはなく、これは undefined behaviour。

23
deceze

PHPマニュアル

演算子の優先順位と結合性は、式のグループ化方法のみを決定し、評価の順序を指定しません。 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++;のような他の行が同じパターンに従うことを期待していたことですが、そうではないようです。

10
Salketer