4

I have found in PHP some strange calculation, for example this:

$c=5;

$r = $c + ($c++ + ++$c);

echo $r;

Why result is 19 and not 17?

Thanks

Jigar Shah
  • 6,143
  • 2
  • 28
  • 41
NeroBuggy
  • 67
  • 2
  • 2
    If an answer solved your problem, consider accepting the answer. Here's how http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work then return here and do the same with the tick/checkmark till it turns green. This informs the community, a solution was found. Otherwise, others may think the question is still open and may want to post (more) answers. You'll earn points and others will be encouraged to help you. *Welcome to Stack!* – Jay Blanchard Oct 24 '17 at 12:01

1 Answers1

3

The result should be unspecified. Please read the following PHP specification:
https://github.com/php/php-langspec/blob/master/spec/10-expressions.md

While precedence, associativity, and grouping parentheses control the order in which operators are applied, they do not control the order of evaluation of the terms themselves. Unless stated explicitly in this specification, the order in which the operands in an expression are evaluated relative to each other is unspecified. See the discussion above about the operators that contain sequence points. (For example, in the full expression $list1[$i] = $list2[$i++], whether the value of $i on the left-hand side is the old or new $i, is unspecified. Similarly, in the full expression $j = $i + $i++, whether the value of $i is the old or new $i, is unspecified. Finally, in the full expression f() + g() * h(), the order in which the three functions are called, is unspecified).

You could find the same reasoning in PHP documentation too: enter image description here

Tarun
  • 3,162
  • 3
  • 29
  • 45
  • In this case though, `precedence, associativity, and grouping parentheses control the order in which operators are applied` for every aspect of the expression – Mark Baker Oct 24 '17 at 12:08
  • @MarkBaker "They control the order in which operators are applied, they do not control the order of evaluation" – Tarun Oct 24 '17 at 12:10
  • Show me how the expression can generate indeterminate results? The question is purely working with specific variables, operator precedence, associativity and grouping.... there is nothing here that can be misinterpreted in any way by the parser, or executed in any different order.... this is purely a case of mathematics – Mark Baker Oct 24 '17 at 12:26
  • @MarkBaker Cant you read what is mentioned in PHP documentation. – Tarun Oct 24 '17 at 12:48
  • Yes!!!! I read what you've posted..... I see absolutely no relevance to what you've posted with regard to the expression that the OP has asked about... that's why I'm asking you to show me how that expression can generate indeterminate results.... which expressions in that purely mathematical formula can be executed in a different order (assuming that precedence, associativity, and grouping parentheses are correctly applied)? Because if you can't trust simple mathematical evaluation, then you can't trust PHP evaluation at all. – Mark Baker Oct 24 '17 at 12:59
  • 1
    Here undefined result means the result could vary with the environment or php version. Please tell me why do you find the example given in documentation irrelevant. I would also suggest you to read about sequence points. – Tarun Oct 24 '17 at 13:16
  • 4
    Out of curiosity https://3v4l.org/bBZQ3, result is 19 in versions: 5.1.0 - 5.6.30, hhvm-3.10.1 - 3.22.0, 7.0.0 - 7.2.0rc4. 17 in versions: 4.3.0 - 5.0.5 – SubjectCurio Oct 24 '17 at 13:28
  • I apologise for being so stupid that I can't understand what I'm saying.... from your description, it seems to me that basically you're saying that If I try to do something like `$c = 0 / 10` then I could get a divide by zero error because it does `10 / 0` instead..... what is being evaluated in `$r = $c + ($c++ + ++$c);` that isn't covered by `precedence, associativity, and grouping parentheses`? – Mark Baker Oct 24 '17 at 14:59
  • You're telling me that my own answer is completely wrong.... please explain why that is the case.... I want to understand why I'm so wrong – Mark Baker Oct 24 '17 at 15:02
  • 2
    Okay, Precedence and parenthesis only tells about grouping rather than ordering of evaluation. Lets say you have $c = $x + $y*$z, Here precedence tells you irrespective of which operand ($x, $y, $z) evaluated first, $y would always be multiplied with $z and result will be added to $x $c = ($x+ ($y*$z)) – Tarun Oct 24 '17 at 16:57
  • 2
    Precedence says nothing about the order in which operand ( or expressio) will be evaluated. The ordering of expression evaluation is determined by sequence point ( Please check above PHP spec for more information ) – Tarun Oct 24 '17 at 16:59
  • So you're saying that in the part of the expression `$c++ + ++$c`, that `++$c` can be evaluated before `$c++`? Or that the addition can be evaluated before the increments? Forgive my stupidity, I've never had any advanced CS type education – Mark Baker Oct 24 '17 at 17:41
  • Lets first apply precedence rule,Say as per precedence, the expression will be grouped as (($c++) + (++$c)), We cant say which expression $c++ or ++$c will be evaluated first. All we know that + would be apply on result of ++$c and $c++. – Tarun Oct 24 '17 at 17:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/157400/discussion-between-tarun-and-mark-baker). – Tarun Oct 24 '17 at 18:20