函数范围静态对象的构造函数抛出异常

时间:2011-08-08 12:32:00

标签: c++ exception static constructor

请考虑以下代码:

#include <iostream>

struct X{
   X(){
      throw 0;
   }
};

void f(){
   static X x;
}

int main(){
   try {
      f();
   }
   catch(int)   {
      std::cout << "Caught first time" << std::endl;
   }
   try {
      f();
   }
   catch(int) {
      std::cout << "Caught second time" << std::endl;
   }
}

该程序的输出是

  

第一次抓到了   第二次抓到了

那么,标准是否保证静态对象的构造函数将被反复调用,直到它成功完成为止?我无法在标准中找到所提到的位置,因此非常欢迎引用或引用章节和诗句。

或者我的示例中是否涉及任何未定义的行为?

1 个答案:

答案 0 :(得分:14)

保证只要失败就会尝试施工。

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

  

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

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

- 结束示例]

我会注意到gcc会在递归初始化尝试时引发异常,请参阅litb's related question作为我的源代码。