Lets say foo is called once in a program, and
void foo()
{
if(sometimes_false())
{
static int xx = func_with_sideeffect();
}
}
the condition wasn't met, is the side-effect
1. Allowed to have happened
2. Mandated to have happened (I'm guessing not if my compiler is conforming)
3. Mandated to not have happened
The non-constant initialization of all variable with local scope and static storage duration is from the point it is encountered till the end of the program. So, if the variable is not encountered because of a condition, it would not be initialized and the side effect won't happen.
The following quote from the standard supports the answer (particularly the part in bold)
6.7 Declaration statement [stmt.dcl]
The zero-initialization (8.5) of all block-scope variables with static storage duration (3.7.1) or thread storage duration (3.7.2) is performed before any other initialization takes place. Constant initialization (3.6.2) of ablock-scope entity with static storage duration, if applicable, is performed before its block is first entered.An implementation is permitted to perform early initialization of other block-scope variables with static orthread storage duration under the same conditions that an implementation is permitted to statically initializea variable with static or thread storage duration in namespace scope (3.6.2). Otherwise such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.88 If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.
The answer is 3 but you need to think about threading.
The static int xx will be initialised by the first thread encountering that variable, and C++11 will block all other threads at that point until func_with_sideeffect() returns and the result has been assigned to xx. (That's not the case with older standards: a mutex would have been required).
It's more difficult to predict the destruction of xx if it was an instance of an object with a non-trivial destructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With