Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's a "recursive_init_error" exception?

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.

like image 664
Johannes Schaub - litb Avatar asked Aug 06 '11 13:08

Johannes Schaub - litb


1 Answers

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.

like image 125
Mat Avatar answered Oct 06 '22 10:10

Mat