I don't understand the pre-increment part in this code - php

Can anyone elexplain to me why the output of this code is 22 not 21?
$x=10;
$x+=++$x;
echo $x;

$x += ++$x;
The right-hand side of this assignment is evaluated first:
increment $x → $x is now 11, result of expression ++$x is 11
take the value of $x (11) and add the result of step 1 to it → 22
assign the result of step 2 to $x

x is being incremented by the stored incremented value of x.
x += (x = x + 1).

Internally, this is evaluated as:
# op ext return operands
-------------------------------------
1 ASSIGN !0, 10
2 PRE_INC $2 !0
3 ASSIGN_ADD 0 !0, $2
4 ECHO !0
Assign 10 to $x (referred to above as !0)
Pre-increment $x, i.e.
Add 1 to $x
Return the new result (11)
Increase $x (now 11) by the return value from step 2 (also 11)
Echo the result (22)
(Edited the VLD output for readability, see the full version here: https://3v4l.org/mftI4/vld#output)

Its all about order of operations.
$a+=$b is just a shorthand for $a = $a + $b. So now, "unroll" your 2nd line with that knowledge:
$x = $x + (++$x);
To assign value to $x, we must 1st evaluate right side of the assignment. To do that, we need first to perform the ++ operation, only then our variables on the right are ready to be added.
So what is operator ++ in this context? It is in turn a shorthand for a function, that does something similar to this:
function preIncrement(&$variable) {
$variable = $variable + 1;
return $variable;
}
Note that variable is a reference (&$variable, rather than $variable). What that means is that inside that function, if we modify variable, it will modify the variable that was passed to it, OUTSIDE. So when we pass $x, the function increases $x and then returns some number value. That number value is being replaced in the right side of the assignment.
So, when that line really looks like is:
$x = $x + postIncrement($x);
So, to evaluate we need to first execute the function in the assignment and get the functions return value. It happens to be 11. Great, now we know we need to add 11 to $x.
$x = $x + 11;
Great, lets just read current value of $x and we can assign. $x is 11. postIncrement function increased it to 11 when we executed it. So:
$x = 11 + 11;
So now, $x is 22.
Lets compare that to post incrementation:
$x+=$x++;
Unrolling += ...
$x = $x + $x++;
As before, we need to get return value of $x++ before we can evaluate. Post incrementation looks something like this:
function postIncrement(&$variable) {
$oldValue = $variable;
$variable = $variable + 1;
return $oldValue;
}
So it takes our $x, increases its value, but returns the original value. As a result, the $x++ gets evaluated as 10. Now we arrive at:
$x = $x + 10;
Ok, lets evaluate $x. $x is 11. Post increment increased it when we executed it. So:
$x = 11 + 10;
So $x is 21 in that case.
Hope this helps you.

Related

Pre Increment in the IF statement has no effect. Why?

The pre-increment in the IF statement has no effect. Can anyone please explain?
<?php
$x = 10;
if($x < ++$x)
{
echo "Hello World";
}
?>
As shown by the opcode dump below, and it shows:
$x is assigned value 10
$x is then incremented to 11 at the memory location
if is executed
Therefore, when you are making the if you are effectivelly comparing variables (memory location) $x with $x and not values 10 and 11.
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > ASSIGN !0, 10
3 1 PRE_INC ~2 !0
2 IS_SMALLER !0, ~2
3 > JMPZ ~3, ->5
5 4 > ECHO 'Hello+World'
7 5 > > RETURN 1
What your code does, is really the following:
<?php
$x=10;
++$x;
if ($x < $x){
The order of evaluation of the operands seems not guaranteed inside a if block, which means the value of $x may be incremented as you seem to expect, or at some other time. the pre_increment has a not well defined behavior.
To fix this, use the increment, it has a very well defined behavior:
<?php
$x = 10;
if ($x < $x++){
echo "hello world";
}
I say the pre_inc behavior is not well defined, because it varies from php interpreter to interpreter. Here's an example of the code that works "as you'd think is expected": https://3v4l.org/n0v6n#v5.0.5
and here's how it "fails": https://3v4l.org/n0v6n#v7.0.25

Why is addition not working instead of increment operator in for loop in PHP?

I needed to increment the for loop by 7 by 7 and used the $x + 7 method as below. However, it didn't work.
for ($x = 1; $x <= 31; $x + 7) {
echo $x ."\n";
}
I solved the problem by redefining the variable as below but I am still wondering why the first method is not working.
for ($x = 1; $x <= 31; $x += 7) {
echo $x ."\n";
}
I usually use the $x++ method to increase the value. Why is $x + 7 different?
You can try: https://glot.io/snippets/g16a4it4il
$x + 7 does not alter x. It simply evaluates to 7 more than $x. To add 7 to $x, you can either:
$x += 7
or
$x = $x + 7
$x++ increments $x by 1. It is roughly equivalent to $x = $x + 1 or $x += 1. (Although when used in an expression, $x++ evaluates to the value of $x before the increment happens; for further information see What's the difference between ++$i and $i++ in PHP?)
The for loop works by changing $x every iteration until $x <= 31 is no longer true.
$x + 7 doesn't change $x, so it'll always remain 1

Why $x=5; $x+++$x++; equals with 11 in PHP?

According to the opcodes it should be 12. Am I getting it wrong?
number of ops: 8
compiled vars: !0 = $x
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------
3 0 E > EXT_STMT
1 ASSIGN !0, 5
5 2 EXT_STMT
3 POST_INC ~2 !0
4 POST_INC ~3 !0
5 ADD ~4 ~2, ~3
6 ECHO ~4
7 7 > RETURN 1
branch: # 0; line: 3- 7; sop: 0; eop: 7; out1: -2
path #1: 0,
Edit
Also ($x++)+($x++); returns the same result (11). Actually this was the main reason for the question and opcode investigation.
It took me a few reads, but $x=5; $x++ + $x++; works like this:
In the case of a $x++, it first 'gets used', then increased:
Set $x to 5
Place $x onto stack (which is 5)
Increment(++) ($x is now 6, stack=[5])
Add $x onto stack (stack=[5,6], so 5+6 -> $x=11)
Adding is done, that outcome is 11
Increment $x(++) (which is isn't used further, but $x is now 7)
Actually, in this specific example, if you would echo $x;
it would output 7. You never reassign the value back to $x, so $x=7 (you incremented it twice);
$x = 5;
$a = $x++ + $x++;
the expression line will be executed like this:
1st occurrence of $x++ in the statement will increment $x value by 1 so it will become 6 and
in 2nd occurrence, $x will be having value 6;
So $a = 5 + 6;
So final result $a will be 11.
++ has higher precedence than + operator
(x++) will return the value of x first then increment it by 1
$x = 2
$x++ // return 2, then increment it to 3
x+++x++ is evaluated like the following
1. Get x value first which is 5
2. Then it will be incremented to 6
3. But first x value will be 5 because (x++) statement will return 5 first then increment the value
4. Then + operator is encountered
5. Next x will have 6 as value not 7 for the same reason (x++) will return the x value first and then increment it
6. So 5+6 is 11
7..At the end, x value will be 7
Same goes for ($x++)+($x++)
grouping operator () has left to right associatevity. First ($x++) executes first.
$x = 5
($x++) returns 5 and then increment $x by 1. Same as before.
then last ($x++) executes. It returns 6 and then increment $x to 7
so same 5+6 // 11 is returned back
The post increment operator increment the variable, but returns its old value.
So $x++ is equivalent to:
($temp = $x, $x = $x + 1, $temp)
When you do it twice in an expression, it's like:
echo ($temp1 = $x, $x = $x + 1, $temp1) + ($temp2 = $x, $x = $x + 1, $temp2);
The first part sets $temp1 = 5 and increments $x to 6.
The second part sets $temp2 = 6 and increments $x to 7.
Then it does $temp1 + $temp2 and echoes the result, which is 5 + 6 = 11.
You are using the post-increment operator ($x++). If you would like to use the incremented value for the addition you should use the pre-increment operator (++$x).
Therefore if $x = 5
$x++ + $x++ equals 5+6 = 11
++$x + $x++ equals 6+6 = 12
$x++ + ++$x equals 5+7 = 12
$++x + ++$x equals 6+7 = 13
Yet in all cases, x is equal to 7 afterward.
$x = 5;
echo $x++ + $x++;
prints 11 as first $x++ returns 5 and then after that it increments, the second $x++ returns 6 and the only value in incremented. so actual addition is 5+6 which gives 11.
++$x + $x++ will be 12
And ++$x + ++$x will be 13
when you use $x++ $x get +1 as soon it's value is use, but the value that will gonna be use is the one it has before the increment, so when yo do:
$x=5; $x+++$x++;
$x+++$x++ is 11, but $x will be 7

why these both post increment in PHP gives the same answer? [duplicate]

This question already has answers here:
PHP operator precedence "Undefined order of evaluation"?
(3 answers)
Closed 5 years ago.
I am trying to run the following code in PHP through localhost, but its giving the unexpected output!
<?php
$a = 1;
echo ($a+$a++); // 3
?>
//answer is 3 but answer should be 2 due to post increment
here is another code and it gives the same answer! why?
<?php
$a = 1;
echo ($a+$a+$a++);
?>
//answer is still 3 !!!
The PHP manual says the following:
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.
So what this comes down to, PHP doesn't explicitly define what the end-result is of those types of statements, and it may even change between PHP versions. We call this undefined behavior, and you shouldn't rely on it.
You might be able to find an exact reason somewhere in the source why this order is chosen, but there might not be any logic to it.
Your two examples are being evaluated as follows:
<?php
$a = 1;
echo ($a + $a++); // 3
?>
Really becomes:
<?php
$a = 1;
$b = $a++;
echo ($a + $b); // a = 2, b = 1
?>
Your second example:
<?php
$a = 1;
echo ($a + $a + $a++); // 3
?>
Becomes:
<?php
$a = 1;
$b = $a + $a;
$a++;
echo $b + $a; // 3
?>
I hope this kind of makes sense. You're right that there's no hard logic behind this.
BEHAVIOR OF INCREMENT OPERATION IN SAME LINE WITH CALCULATION IS NOT DEFINIED!
Compilator can generate different code then you expect.
Simple answer from my teacher:
NEVER USE INCREMENT/DECREMENT OPERATOR IN SAME LINE WITH CALCULATIONS!
It's behavior is undefined - computers calculate in different order then humans.
GOOD:
$d = $i++;
$i++;
for ($i = 0; $i < 5; $i++)
CAN BE A PROBLEM (you can read it wrong):
$d = $array[$i++];
WILL BE A PROBLEM:
$d = $i++ + 5 - --$k;
EDIT:
I wrote same code in C++. Checked Assembler code and result is as I said:
Math with increment is not logic for people, but you can't say that someone implemented it wrong.
As someone posted in comment:
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > ASSIGN !0, 1
3 1 POST_INC ~2 !0
2 ADD ~3 !0, ~2
3 ECHO ~3
16 4 > RETURN 1
//$a = 1;
//echo ($a+$a++);
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > ASSIGN !0, 1
3 1 ADD ~2 !0, !0
2 POST_INC ~3 !0
3 ADD ~4 ~2, ~3
4 ECHO ~4
5 > RETURN 1
//$a = 1;
//echo ($a+$a+$a++);
Translated to human language:
$a = 1;
echo ($a + $a++);
// After changing to 'computer logic' (ASM):
$c = 1; // for increment operation
$b = $a; // keep value 'before' add +1 operation
$a += $c; // add +1 operation
$d = $a + $b; // calculate value for 'echo'
echo $d; // print result
Its because the ++ sign is an incremental operator to a variable. So your
$a = 1
$a++ = 2
($a+$a++) = (1+2) = 3
Thats why it shows 3 as the answer.

What will be output of below php program

I have a program in php that will based on post and pre increment like
<?php
$x=5;
echo $x+++$x++;
?>
I execute program and output is 11 but i confused why it prints 11.can anyone please explain how this program execute.
The postincrement operator increments the variable, but returns its old value. So $x++ is equivalent to:
($temp = $x, $x = $x + 1, $temp)
When you do it twice in an expression, it's like:
echo ($temp1 = $x, $x = $x + 1, $temp1) + ($temp2 = $x, $x = $x + 1, $temp2);
The first part sets $temp1 = 5 and increments $x to 6. The second part sets $temp2 = 6 and increments $x to 7. Then it does $temp1 + $temp2 and echoes the result, which is 5 + 6 = 11.
x++ is called postincrement, it returns x and then increases x by one. Opposite is ++x ( preincrement ), increase x by one and then return. + in the middle is arithmetic operator for addition.
$x = 5;
echo $x++ + $x++; // 11
echo $x; // 7
This: echo $x+++$x++ is the same as:
echo ( ($x++) + ($x++) )
So, as you can see, its adding $x++ plus $x++
In PHP, when you run $x++, is the same as saying $x = $x + 1 but returning the original value of $x. (As said in the comments)
So for example if you do this:
$x = 5;
echo $x++; //outputs $x, then adds 1
echo $x++; //outputs $x, then adds 1
/*
THIS IS WHAT THE ABOVE DOES:
set x equal to 5
echo x (OUTPUTS 5), then add 1.
echo x (OUTPUTS 6), then add 1.
*/
With that said, in $x+++$x++, the first reference of $x is when its value is still 5 (before it is incremented) and the second reference to $x is then when its value is 6 (before it is again incremented), Therefore: 5 + 6 = 11
Source: http://php.net/manual/en/language.operators.increment.php

Categories