什么是“recursive_init_error”例外?

发布于 2024-11-28 18:28:28 字数 457 浏览 1 评论 0原文

我决定使用计算的 goto 和本地静态进行测试,

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(); }

我想看看输出是否为“init init!”。但令我惊讶的是,我没有得到该输出,而是 GCC 优雅地处理了它,在运行时输出:

init terminated by recursive_init_error: exception

那个异常是什么?这是标准例外吗? C++03 还是 C++0x?感谢您的任何解释。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

忘年祭陌 2024-12-05 18:28:28

这是由 C++03 §6.7/4 中所述引起的:

...否则,此类对象将在控件第一次通过其声明时被初始化;这样的对象在其初始化完成后就被视为已初始化。如果初始化通过抛出异常退出,则初始化尚未完成,因此下次控制进入声明时将再次尝试。如果在初始化对象时控制重新进入声明(递归地),则行为是未定义的。 [示例:

int foo(int i)
{
  static int s = foo(2*i);    // recursive call – undefined
  return i+1;
}

--结束示例]

在这种情况下,GCC 会抛出异常。这是关于它的一些文档


C++11 更新:C++11 中在有关递归情况的文本之前添加了以下措辞:

如果在变量初始化时控制同时进入声明,则并发执行将等待初始化完成。88

88 实现不得在初始化程序的执行周围引入任何死锁。

不会改变这里的问题,但会在没有递归时使此构造线程安全。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文