3v4l.org

run code in 300+ PHP versions simultaneously
<?php // #1 function test1(){ echo PHP_EOL.__function__ .":"; $a=1; echo (++$a)+(++$a); } test1(); // 5 // #2 function test2(){ echo PHP_EOL.__function__ .":"; $a=1; $b=&$a; echo (++$a)+(++$a); } test2(); // 6(5.1.1 - 5.6.24) or 5(hhvm, 7.0.0+) // #3 function test3(){ echo PHP_EOL.__function__ .":"; $a=1; $b=&$a; echo (++$a)+(++$a)+(++$a); } test3(); // 10(5.1.1 - 5.6.24) or 9(hhvm, 7.0.0+) // #4 function test4(){ echo PHP_EOL.__function__ .":"; $a=1; // $b=&$a; echo $a + $a++; } test4(); // 3 // #5 function test5(){ echo PHP_EOL.__function__ .":"; $a = 1; // $b = &$a; // echo @$a + $a++; // 2 echo $a + $a++; // 3 } test5(); // 3 // #6 function test6(){ echo PHP_EOL.__function__ .":"; $a = 1; echo $a + $a + $a++; } test6(); // 3 /* 从上面的结果来看,有以下三点必须知识: - ++$a 是自己加1,之后的都要加1;如果是指针引用,有些版本会导致 ++$a 的临时值为自身,让之前的计算结果也改变。 - $a++ 是自己不用增1的结果,但是这个操作符之后的都要加1,不管有没有指针引用。 - 编译器每一次都要把表达式组合成两元组:((($a++ + $a) + $a) + $a); 但是在 ($a + $a++) 的情况下,会改变顺序为 ($a++ + $a),所以 $a++ + $a 的结果是3. 最终版本(php v7.0)(`$a = 1; $b = &$a; echo ++$a + ++$a + $a;`) compiled vars: !0 = $a, !1 = $b line #* E I O op fetch ext return operands ------------------------------------------------------------------------------------- 2 0 E > ASSIGN !0, 1 3 1 ASSIGN_REF !1, !0 4 2 PRE_INC $4 !0 3 PRE_INC $5 !0 4 ADD ~6 $4, $5 5 ADD ~7 ~6, !0 6 ECHO ~7 5 7 ECHO !0 8 > RETURN 1 from: https://3v4l.org/fgLZO/vld#tabs 注意: > 不同的php 版本不同,导致的结果不同。我用 c++ 测试过,gcc 和 clang 的结果也不同(当然会有warning). 总结: - 目前hhvm和7.0.0+都不再会受到指针引用的影响。(受影响的版本 5.1.1 - 5.6.24) - `++a;++a`, clang 结果是6, gcc 结果是5 - 混写的写法:不易查错,不易 debug,全语言混乱 - 建议:所有自增全部用新行写 */ // four quiz function quiz() { echo PHP_EOL.__function__ .":"; $a=1; $b=&$a; echo ($a++)+(++$a); $a=1; $b=&$a; echo (++$a)+($a++); $a=1; //$b=&$a; echo (++$a)+($a++); $a=1; $b=&$a; echo (++$a)+(++$a); } quiz(); // answer: 4445(hvvm,7.0.0+) 4556(4.3.0 - 5.6.24) // Good points from above // #0.1 // $a = -1; // var_dump($a && true); // true // var_dump($a && false); // false // var_dump($a && -1); // true // #0.2 // $a + $a + $a + $a + $a // + is left-assoc, so it's grouped as // (((($a + $a) + $a) + $a) + $a) // #0.3 // $a + $a + $a + $a + $a // $a = $b = $c = $d = $e // = is right-assoc, so it's grouped as // ($a = ($b = ($c = ($d = $e))))

preferences:
160.96 ms | 405 KiB | 5 Q