Оценка неинтуитивного выражения с инкрементацией - программирование
Подтвердить что ты не робот

Оценка неинтуитивного выражения с инкрементацией

Для следующего кода

<?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) (построено: 11 мая 2017 14:07:52) (NTS)

4b9b3361

Ответ 1

$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.

Ответ 2

В PHP нет (в общем случае) указать, в каком порядке оценивается выражение, а код, который предполагает определенный порядок оценки, следует избегать [..]

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

Причина, по которой вы получаете разные результаты, заключается в том, что иногда сначала оцениваются правый, а иногда и левый операнд. PHP не дает никаких гарантий относительно порядка операций, поэтому нет правильного ответа, и это прямо относится к категории undefined.

Ответ 3

Согласно руководство по 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++;, будут следовать одному и тому же шаблону, но это не так.