I have seen a question on stack over flow.
What's happening with this expression? b = a + (a = a + 5)
It shows the value of b will be 15. But when i run this code on Php, value of b is 20.
Why there is difference of output in php and C#
It's happens because PHP and C# differently used memory for save variables.
Read How PHP manages variables.
So PHP not duplicated zval memory for variable "$a" and value of $a changed when ($a = $a +5) has been completed so we have that
$a = 5;
echo $a + ($a = $a + 5); //20
and C# has duplicated memory for a variables read answer What's happening with this expression? b = a + (a = a + 5).
I've been looking around and found formula: a = (a + b) - (b = a) it is supposed to swap two variables (or objects in some cases). However I tested it with C++ and php, these gave me different result.
php:
$a = 10;
$b = 20;
$a = ($a + $b) - ($b = $a);
echo $a, " ", $b;
This prints 20 10
C++
int a = 10;
int b = 20;
a = (a + b) - (b = a);
std::cout << a << " " << b;
This prints 10 10
Code looks the same but outputs are different, I've been thinking about two reasons:
C++ code is compiling and php is interpreting.
This formula is useless because it leads to undefined behavior.
Can somebody explains, why C++ and php output differs in this situation?
I'm not sure what the rules are in PHP, but in C++, the order of individual sub-expressions isn't strictly defined, or as the technical term is, it is "unspecified" - in other words, the compiler is allowed to calculate b = a before or after it does a + b. As long as it does a + b and b = a before the subtraction. The use of "unspecified" behaviour allows the compiler to produce more efficient code in some cases, or simply that it's possible to build a compiler for some architectures.
It also means that if you have an expression that "recalculates" a value within the expression itself, and also using it elsewhere in the expression, you get unedefined behaviour (UB for short). UB means just that, the behaviour is not defined - almost anything could happen, including what you are seeing and many other alternatives (e.g. the compiler is allowed to produce 42 as a result as well, even if logic says the answer wouldn't be 42 in this case [it's the wrong question for that!]).
I would also suggest that if you want to swap two values, in PHP:
$t = $a;
$a = $b;
$b = $t;
and in C++:
#include <algorithm>
std::swap(a, b);
or if you insist on writing your own:
int t = a;
a = b;
b = t;
Trying to be clever and perform it "without temporary variable" is almost certainly going to make it slower than the use of a temporary - certainly in a compile language like C++ - in a interpreted language like PHP, creating a new variable may add a bit of extra overhead, but it's unlikely to be that big, compared to the extra effort in the logic required.
C++ code is completely broken because of undefined behavior. (read and write b in one sequence point).
For PHP:
$a = 10;
$b = 20;
$a = ($a + $b) - ($b = $a);
//executes like thus
$a = (30) - ($b = $a);
$a = (30) - ($b = $a = 10); //new $a still not computed, using older $a
$a = (30) - (10);
$a = 20;
//then, $a=20 and $b = 10
This is totally related to Operator Precedence, this might be same in C or might not, it depends on precedence if unexpected behavior not occur.
This question already has answers here:
Why is $a + ++$a == 2?
(13 answers)
Closed last year.
As i know, preincrement is calculated before all other operations, postincrement is calculated after all operations.
In php docs it is said that increment (as i understand exactly pre-increment) has very high precedence. Post-increment should have very low precedence, in fact, lowest one.
+ operator precedence is MUCH MORE lower then ++ one (acording to docs).
So, now the question: In php docs there is an example, that shows that preincrement and postincrement in one expression can vary:
// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5
Why? WTF? I see following scenario an it is very clear:
Preincrement $a
Calculate sum for $a and $a
Post increment $a
I can't understand why it is unpredictable.
PHP documentation regarding this subject (and also this example) could be found there:
http://www.php.net/manual/en/language.operators.precedence.php
It would always produce 4 because the last $a is using Post-increment for it to produce 5 then use Pre-increment like the first $a
$a = 1;
echo ++ $a + $a++; // 4
And
$a = 1;
echo ++ $a + ++ $a; // 5
Incrementing/Decrementing Operators
This question already has answers here:
Why is $a + ++$a == 2?
(13 answers)
Closed 10 years ago.
In the PHP manual, operator precedence section, there is this example:
// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5
I understand the behavior is undefined because of the following reason:
Since x + y = y + x the interpreter is free to evaluate x and y for addition in any order in order to optimize speed and/or memory. I concluded this after looking at the C code example in this article.
My question is that the output of the above mentioned PHP code should be 4 no matter which way the expression and sub-expressions are evaluated:
op1 = ++$a => $a = 2, op1 = 2; op2 = $a++ => op2 = 2, $a = 3; 2 + 2 = 4
op1 = $a++ => op1 = 1, $a = 2; op2 = ++$a => op2 = 3, $a = 3; 1 + 3 = 4
Where does the 5 come from? Or should I learn more about how the operators work?
Edit:
I have been staring at Incrementing/Decrementing Operators section but still could not figure out why 5.
++$a: Pre-increment -- Increments $a by one, then returns $a.
$a++: Post-increment -- Returns $a, then increments $a by one.
a = 1;
++ (preincrement) gives a = 2 (higher precedence than +, and LR higher precedence than postincrement)
++ (postincrement) gives a = 3 (higher precedence than +)
+ (add) gives 2 + 3 = 5
$a is initially set to 1. The ++$a then preincrements $a before using it in the formula, setting it to 2, and pushing that value onto the lexer stack. The $++ is then executed, because incrementor has a higher precedence than +, and that value is also pushed that result onto the lexer stack; and the addition that then takes place adds the lexer stack's 2 result to the lexer stack's 3 result giving a result of 5, which is then echoed. The value of $a once the line has executed is 3.
OR
a = 1;
++ (preincrement) gives a = 2 (higher precedence than +, and LR higher precedence than postincrement)
+ (add) gives 2 + 2 = 4 (the value that is echoed)
++ (postincrement) gives a = 3 (incremented __after__ the variable is echoed)
$a is initially set to 1. When the formula is parses, the ++$a preincrements $a, setting it to 2 before using it in the formula (pushing the result to the lexer stack). The result from the lexer stack and the current value of $a are then added together giving 4; and this value is echoed. Finally, $a is postincremented, leaving a value of 3 in $a.
Yes it will give you 5 because the right side operator works first by its priority/precendence and after that the sum(+) operator will work.
So first increment makes it to 2 and second makes it to 3 and after that both will sum and outputs you the result as 5
$result = ++$a + $a++;
++$a outputs as 2
$a++ outputs as 2 3 only but internally it wll be incremented.
finally sum will happens as 2+3 = 5
Mark, I believe you are wrong!
Post-increment: Returns $a, then increments $a by one. (from documentation)
So there is no way to get $a value of 3 in sum operation.
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?
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:
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.
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?"
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
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:
Order of evaluation in PHP (Sep 2013; by NikiC) (via)
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.
++ is the higher precedence operator, so it gets applied first.
So now l = 1.
So 1 + 1 = 2.
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.
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.
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
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
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.
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;
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;
Get $l: $l = 0
Apply ++: ++$l = 1
Get $l: $l = 1
Apply +: $l + $l = 1 + 1 = 2
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