http://3v4l.org/uVNIS Prior to PHP 5.1 (and the introduction of compiled variables), the following code would output warnings for the undefined variables in the order they were used:
echo $x . $y . $z; However, with the introduction of CVs, we wind up getting the warning for $y, then $x, and finally $z. ((Insert "middle-out" reference from HBO's Silicon Valley, here)) The reason for this, is that ZEND_CONCAT (and indeed, most binary operations) is implemented as a single inline function call: concat_function(EX_VAR(opline->result.var), GET_OP1_ZVAL_PTR(BP_VAR_R), GET_OP2_ZVAL_PTR(BP_VAR_R)); When gcc looks at this function call, it treats the execution order for the arguments as undefined. In practice (at least on 3v4l.org) it ends up evaluating the third argument (OP2) first, then the second argument (OP1), and finally the first argument (result.var). This is perfectly legal as far as GCC is concerned since the result of one function call argument shouldn't have side effects relative to another argument. I'd like to propose making the order of evaluation defined by splitting this into separate statements: zval *op1 = GET_OP1_ZVAL_PTR(BP_VAR_R); zval *op2 = GET_OP2_ZVAL_PTR(BP_VAR_R); concat_function(EX_VAR(opline->result.var), op1, op2); The optimizer should do a proper job of removing the intermediate assignment while keeping the defined resolution order intact. God help us if anyone is actually /depending/ on this behavior... -Sara -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php