php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78829 数字传引用计算问题
Submitted: 2019-11-18 09:35 UTC Modified: 2019-11-18 16:58 UTC
From: 1003674174 at qq dot com Assigned:
Status: Not a bug Package: Variables related
PHP Version: 7.3.11 OS: windows
Private report: No CVE-ID: None
 [2019-11-18 09:35 UTC] 1003674174 at qq dot com
Description:
------------
php5.6echo的值是6,php7的值是5

Test script:
---------------
$a=1;$b=&$a;echo (++$a)+(++$a);exit;


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-11-18 13:11 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2019-11-18 13:11 UTC] cmb@php.net
Isn't 5 the output one would expect?
 [2019-11-18 15:12 UTC] requinix@php.net
-Status: Feedback +Status: Not a bug -Assigned To: cmb +Assigned To:
 [2019-11-18 15:12 UTC] requinix@php.net
It's about the undefined execution order.

https://www.php.net/manual/zh/language.operators.precedence.php
> 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.
>
> Example #2 Undefined order of evaluation
  <?php
  $a = 1;
  echo $a + $a++; // may print either 2 or 3

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

(the page is already marked as needing a translation update)
 [2019-11-18 16:22 UTC] cmb@php.net
> It's about the undefined execution order.

I don't think so, since it doesn't matter whether `(++$a)` is
evaluated before `(++$a)` or the other way round.  It rather
seems to me that PHP < 7 got confused by the reference.
 [2019-11-18 16:27 UTC] requinix@php.net
-Status: Not a bug +Status: Feedback
 [2019-11-18 16:27 UTC] requinix@php.net
Sorry yes, you're right, it's a pre-increment in there, and the reference does (did) matter.

5 is the correct output - I'm not sure how it came up with 6 before.
 [2019-11-18 16:33 UTC] requinix@php.net
Of course the minute after I send that I figure it out.

The reference mattered because ++$a incremented $a and then "returned" $a. In other words,
  ++$a;
  ++$a;
  echo ($a)+($a);

When PHP 7 changed references and introduced AST and redid everything else, that nuance disappeared and the expression would properly return the *value of* $a, regardless of whether the variable was a reference or not.
While I don't remember a specific example, I know there have been a few bug reports about this same change in behavior with similar situations. I might be able to find one...
 [2019-11-18 16:58 UTC] requinix@php.net
-Status: Feedback +Status: Not a bug
 [2019-11-18 16:58 UTC] requinix@php.net
Two bugs about the incorrect behavior in PHP 5,
  https://bugs.php.net/bug.php?id=71010
  https://bugs.php.net/bug.php?id=65580
both closed NAB due to undefined behavior with sequence points.

PHP 7's behavior does make more sense, but it's still technically undefined.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Wed Apr 21 19:01:23 2021 UTC