【问题标题】:What's a "recursive_init_error" exception?什么是“recursive_init_error”异常?
【发布时间】:2011-08-06 13:39:39
【问题描述】:

我决定使用计算的 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?感谢您的任何解释。

【问题讨论】:

  • 我认为 {} 不能出现在 () 中。
  • @Eric 谢谢,我添加了 gnu-c++
  • @dauphic:我认为你通过对他的内容投票而不是基于你的粉丝主义来获得更大的帮助。这也是应该的。

标签: c++ exception initialization g++


【解决方案1】:

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

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

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

--结束示例]

在这种情况下,GCC 会引发异常。这是some documentation 的相关信息。


C++11 更新:在 C++11 中添加了以下措辞,就在关于递归案例的文本之前:

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

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

并没有改变这里的问题,但是在没有递归时确实使这个构造线程安全。

【讨论】:

  • +1 用于提供一个简单、标准的 C++ 示例来说明 OP 问题的核心,我会再提供一个 +1 用于将文档链接到 OP 编译器的响应。
  • 澄清一下,这个例子是直接取自标准的,不是我想出来的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 2014-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-06
相关资源
最近更新 更多