Неинтуитивная оценка выражений с приращением

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

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

46

Решение

$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

Другие решения

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

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

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

23

В соответствии с Руководство по 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
По вопросам рекламы [email protected]