rfc:arbitrary_static_variable_initializers

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
rfc:arbitrary_static_variable_initializers [2023/03/15 16:58] – Fix out-dated comment on ReflectionFunction::getStaticVariables() ilutovrfc:arbitrary_static_variable_initializers [2023/03/16 12:31] ilutov
Line 105: Line 105:
 foo(2); foo(2);
 var_dump((new ReflectionFunction('foo'))->getStaticVariables()['x']); var_dump((new ReflectionFunction('foo'))->getStaticVariables()['x']);
-// 2+// 1
 </code> </code>
  
Line 195: Line 195:
 // string(4) "Done", $i = 5, initializer not called // string(4) "Done", $i = 5, initializer not called
 </code> </code>
 +
 +==== What initializers are known at compile-time? ====
 +
 +In the discussion the question arose whether static variables depending on other static variables are known at compile time.
 +
 +<code php>
 +function foo() {
 +   static $a = 0;
 +   static $b = $a + 1;
 +}
 +</code>
 +
 +The answer is no. In this example it's clear that <php>$a</php> holds the value <php>0</php> until the initialization of <php>$b</php>. However, that's not necessarily the case. If <php>$a</php> is modified at any point between the two initializations the initial value of <php>$b</php> also changes.
 +
 +Here's a quick explanation of how this is implemented: During compilation of static variables the initializer AST is passed to the <php>zend_eval_const_expr</php> function. It traverses the AST and tries to compile-time evalute all nodes by evaluating their children fist and then the node itself if the child nodes were successfully evaluated. If the evaluation fails the nodes stay AST nodes and will again be evaluated at runtime when more information is available (e.g. when class constant are declared). These expressions are currently considered for compile-time constant expression evaluation:
 +
 +  * Literals (strings, ints, bools, etc)
 +  * Binary operations
 +  * Binary comparisons
 +  * Unary operations
 +  * Coalesce operator
 +  * Ternary operator
 +  * Array access (<php>self::FOO['bar']</php>)
 +  * Array literals
 +  * Magic constants (e.g. <php>__FILE__</php>)
 +  * Global constants (that are known at compile time)
 +  * Class constants (that are known at compile time)
  
 ===== Vote ===== ===== Vote =====
rfc/arbitrary_static_variable_initializers.txt · Last modified: 2023/05/24 18:29 by ilutov