I decided to do a test with computed gotos and local statics
void g() { std::cout << "init "; }
void f() {
int z = 0;
y: z++;
static int x =
(g(), z == 1 ? ({ goto *&&y; 0; }) : 0);
}
int main() { f(); std::cout << "!"; f(); }
I wanted to see whether the output would be "init init !". But to my surprise I didn't get that output, but instead GCC handled it gracefully, outputting at runtime:
init terminated by recursive_init_error: exception
What's that exception? Is it a Standard exception? C++03 or C++0x? Thanks for any explanation.
It's caused by what is stated in C++03 §6.7/4:
... Otherwise such an object is initialized the first time control passes through its declaration; such an object 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 re-enters the declaration (recursively) while the object is being initialized, the behavior is undefined. [Example:
int foo(int i)
{
static int s = foo(2*i); // recursive call – undefined
return i+1;
}
--end example]
GCC throws an exception in that case. Here's some documentation about it.
C++11 update: The following wording was added in C++11, just before the text about the recursive case:
If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.88
88 The implementation must not introduce any deadlock around execution of the initializer.
Doesn't change the problem here, but does make this construct thread-safe when there is no recursion.
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