What's a “recursive_init_error” exception?

2019-02-21 16:40发布

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.

1条回答
可以哭但决不认输i
2楼-- · 2019-02-21 17:21

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.

查看更多
登录 后发表回答