Why is $a + ++$a == 2?

PhpMathOperator Precedence

Php Problem Overview


If I try this:

$a = 0;    
echo $a + ++$a, PHP_EOL;
echo $a;

I get this output:

2
1

Demo: http://codepad.org/ncVuJtJu

###Why is that?

I expect to get this as an output:

1
1

###My understanding:

$a = 0;                    // a === 0    
echo $a + ++$a, PHP_EOL;   // (0) + (0+1) === 1
echo $a;                   // a === 1

But why isn't that the output?

Php Solutions


Solution 1 - Php

All the answers explaining why you get 2 and not 1 are actually wrong. According to the PHP documentation, mixing + and ++ in this manner is undefined behavior, so you could get either 1 or 2. Switching to a different version of PHP may change the result you get, and it would be just as valid.

See example 1, which says:

// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5

Notes:

  1. Operator precedence does not determine the order of evaluation. Operator precedence only determines that the expression $l + ++$l is parsed as $l + (++$l), but doesn't determine if the left or right operand of the + operator is evaluated first. If the left operand is evaluated first, the result would be 0+1, and if the right operand is evaluated first, the result would be 1+1.

  2. Operator associativity also does not determine order of evaluation. That the + operator has left associativity only determines that $a+$b+$c is evaluated as ($a+$b)+$c. It does not determine in what order a single operator's operands are evaluated.

Also relevant: On this bug report regarding another expression with undefined results, a PHP developer says: "We make no guarantee about the order of evaluation [...], just as C doesn't. Can you point to any place on the documentation where it's stated that the first operand is evaluated first?"

Solution 2 - Php

A preincrement operator "++" takes place before the rest of the expression it's in evaluates. So it is actually:

echo $l + ++$l; // (1) + (0+1) === 2

Solution 3 - Php

a + b

a = 1
b = ++a

:= 2

Why do you expect something else?

In PHP:

$a = 0;
$c = $a + ++$a;

Operator precedence visualized:

$c = ($a) + (++$a);

Evaluation sequence visualized:

$a = 0; ($a = 0)
$a = 1; (++$a)
$c = $a + $a (1 + 1);

Or written out:

The moment the sum operation is performed, $a is already 1 because ++$a has been already evaluated. The ++ operator is evaluated before the + operator.


For the fun:

$a++ + ++$a

Results in 2, too. However if you compare it as an expression, it's not equal:

$a++ + ++$a == $a + ++$a

Where as

$a++ + ++$a == $a-- + --$a 

is "equal".


See Also:

Solution 4 - Php

My Evaluation Order in PHP blog post explain this in detail, but here is the basic idea:

  • Operator precedence and associativity have nothing to do with evaluation order.
  • PHP does not guarantee an evaluation order. The order can change between PHP versions without notice and can also be different depending on the surrounding code.
  • "Normally" PHP will evaluate left-to-right, with the exception of accesses to "simple" variables (like $a). Accesses to simple variables will be executed after more complex expressions, regardless in which order the expressions actually occur.
  • In this particular case it means that ++$a is run first because it is a complex expression and only then the value of $a is fetched (it is already 1 at this point). So effectively you are summing 1 + 1 = 2.
  • The reason that simple variables are fetched after complex expressions is the Compiled Variables (CV) optimization. If you disable this optimization, for example by using the @ error suppression operator, all expressions are evaluated left-to-right, including simple variable fetches.
  • In this particular case it means that @($a + ++$a) will result in 1, because first $a is fetched (0 at that time) and incremented only after that.

Solution 5 - Php

++ is the higher precedence operator, so it gets applied first.

So now l = 1.

So 1 + 1 = 2.

Solution 6 - Php

When you do your ++$l (preincrement), it will be done before your addition -> check operator precedence).

So, the value of $l will be 1 before your addition :

echo $l + ++$l; // $l => 1  because ++$l is done first

So your answer will be 2.

But when you do :

echo $l // you will get your first value which is $l => 1

So your answer will be 1.

Solution 7 - Php

This behaviour can be confirmed by inspecting how PHP compiles your script, for example:

$a = 0;
echo $a + ++$a;

Compiles into the following opcodes, which are then executed:

compiled vars:  !0 = $a
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   1     0  >   ASSIGN                                                   !0, 0
         1      PRE_INC                                          $1      !0
         2      ADD                                              ~2      !0, $1
         3      ECHO                                                     ~2
         4    > RETURN                                                   null

This translates to the following equivalent script:

$a = 0;              // ASSIGN
$tmp = ++$a;         // PRE_INC
echo $a + $tmp;      // ADD, ECHO

Conclusion

By the time $a is evaluated as the left hand expression of $a + (++$a), it has already been incremented, because ++$a was evaluated first.

Obviously, this behaviour should not be relied upon; in any language for that matter.

Solution 8 - Php

Check the increment operator manual:

http://www.php.net/manual/en/language.operators.increment.php

Or see this codepad: http://codepad.org/Y3CnhiLx

<?php

$n = 0;
$m = 0;
echo '++ before:';
echo $n+ ++$n;
echo PHP_EOL;
echo '++ after:';
echo $m+ $m++;
echo PHP_EOL;
echo 'n:'.$n;
echo PHP_EOL;
echo 'm:'.$m;

Outputs:

++ before:2
++ after:1
n:1
m:1

Solution 9 - Php

As you may know we have two increment operator, one is pre-increment and second is post-increment. Pre-increment increase the value of integer before it use in expression, on the other hand post increment increase value of number after it used in expression.

suppose you have variable $a and variable $b as below

$a=0;

$b=++$a gives the value of b=1

while

$b=$a++ gives the value b=0

Solution 10 - Php

The output of your code varies with PHP version as seen here

> Output for 4.3.0 - 5.0.5
> 1
> 1

In the above case the left hand side of + operator is evaluated first (0, 1, +).

> Output for 5.1.0 - 5.5.0alpha4
> 2
> 1

In the above case the right hand side of + operator is evaluated first (1, 1, +).

This is in accordance with interjay's answer that in PHP there is no guarantee about the order of evaluation of sub-expresions. The assumption that the output could be 1, 1 is correct, so are that answers that claim that the output could be 1, 2.

Solution 11 - Php

First obvious part is that ++ have higher priority than +.

Second part is that php engine doesn't store value from first operand into another anonymous variable. So $l + ++$l is not an qeuivalent for

$a = $l;
$b = ++$l;
return $a + $b;

Solution 12 - Php

As mentioned before there is a difference in x++ and ++x. You can interpret it in the way that

x++;

increments after the semicolon

and

++x;

increments on evaluation of the expression

So it seems that your expression is evaluated from right to left

echo $l + ++$l;

2. Get $l: $l = 0 3. Apply ++: ++$l = 1

  1. Get $l: $l = 1
  2. Apply +: $l + $l = 1 + 1 = 2

Solution 13 - Php

All statements are executed from right to left. So the value is first incremented than the value of your variable is = 1 so 1+1=2

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNaftaliView Question on Stackoverflow
Solution 1 - PhpinterjayView Answer on Stackoverflow
Solution 2 - PhpDennisView Answer on Stackoverflow
Solution 3 - PhphakreView Answer on Stackoverflow
Solution 4 - PhpNikiCView Answer on Stackoverflow
Solution 5 - PhpJohn3136View Answer on Stackoverflow
Solution 6 - PhpChapMicView Answer on Stackoverflow
Solution 7 - PhpJa͢ckView Answer on Stackoverflow
Solution 8 - PhpGuumasterView Answer on Stackoverflow
Solution 9 - Phpkundan boraView Answer on Stackoverflow
Solution 10 - PhpSalman AView Answer on Stackoverflow
Solution 11 - PhpkirilloidView Answer on Stackoverflow
Solution 12 - PhpTarionView Answer on Stackoverflow
Solution 13 - PhpFawad GhafoorView Answer on Stackoverflow