当函数中静态变量的构造函数异常终止时会发生什么
What happen when the constructor of a static variable in a function terminates unusually?
我有一个函数可以简化为:
void f() {
static MyObject o("hello");
DoSomethingWith(o);
}
这个函数是跨 C API 边界调用的,所以像个好孩子一样,我使用 try
来捕获在它们越过边界之前抛出的任何异常并搞砸事情:
void f() {
try {
static MyObject o("hello");
DoSomethingWith(o);
} catch (const MyObjectException& e) {
Message("Constructor of o failed");
}
}
第一次调用此函数,我收到消息"Constructor of o failed"
.但是,稍后,再次调用该函数,我再次收到消息。我收到消息的次数与调用f
一样多。我正在使用Visual C++所以这告诉我MSVC++做什么,而不是应该做什么。
我的问题是,当static
函数变量的构造函数异常终止时会发生什么(通过throw
ing,构造函数的longjmp
,它所在的线程的终止等(?另外,在它之前和之后声明的任何其他static
变量应该会发生什么?我也希望从标准中获得任何相关报价。
C++11标准第6.7([stmt.dcl]
(节
在进行任何其他初始化之前,将执行具有静态存储持续时间 (3.7.1( 或线程存储持续时间 (3.7.2( 的所有块范围变量的零初始化 (8.5(。具有静态存储持续时间的块范围实体的常量初始化 (3.6.2((如果适用(在首次输入其块之前执行。允许实现使用静态或 线程存储持续时间与允许实现在命名空间范围 (3.6.2( 中使用静态或线程存储持续时间静态初始化变量的条件相同。 否则,此类变量在控件第一次通过其声明时初始化;此类变量在其初始化完成后被视为已初始化。 如果初始化通过引发异常退出,则初始化 不完整,因此下次控件进入声明时将再次尝试。 如果在初始化变量时控件并发进入声明,则并发执行应等待初始化完成。 如果控件在变量正在时递归地重新输入声明 已初始化,行为未定义。
问:当静态函数变量的构造函数异常终止时会发生什么 [...] ?
答:
§6.7 [stmt.dcl] p4
[...]否则,此类变量在控件第一次通过其声明时初始化;此类变量在其初始化完成后被视为已初始化。如果初始化通过引发异常退出,则初始化未完成,因此下次控件进入声明时将再次尝试初始化。
因此,如果o
通过引发异常退出,则将再次尝试初始化。我认为这同样适用于任何类型的异常退出初始化,尽管没有明确说明。Brb,寻找更多报价。
由于我找不到任何相关内容,因此我打开了一个后续问题。
问:另外,在它之前和之后声明的任何其他静态变量应该怎么做?
答:没有,只要线程或整个程序都不终止。
§3.6.3 [basic.start.term]
具有静态存储持续时间的初始化对象(即生存期 (3.8( 已开始的对象(的析构函数 (12.4( 由于从
main
返回和调用std::exit
(18.5( 而被调用。给定线程中具有线程存储持续时间的初始化对象的析构函数由于从该线程的初始函数返回以及该线程调用std::exit
的结果而被调用。在该线程中具有线程存储持续时间的所有初始化对象的析构函数的完成是在启动具有静态存储持续时间的任何对象的析构函数之前排序的。
§3.7.2 [basic.stc.thread]
具有线程存储持续时间的变量应在首次使用 (3.2( 之前初始化,如果构造,则应在线程退出时销毁。
你的程序。将尝试初始化静态变量,直到初始化成功。如果这种模式不合适,你应该找到一种更好的方式来表达你的目标。也许是在受控环境中填充的静态unique_ptr
?如果你有一个无法可靠地构造的资源,你必须将构造降级到可以处理错误的其他上下文中,或者让你的函数只选择性地依赖于资源(例如,通过空指针(。
- 是什么导致了Unity 3D中的"错误线程异常"?
- C++异常被捕获延迟,可能导致这种情况的原因是什么?
- 您应该在什么时候创建自己的异常类型
- 等待 qthread 终止的正确方法是什么?
- ZMQ::send() 抛出异常并终止 QNX 进程.为什么以及如何从中恢复?
- 终端(bash)如何知道引发了什么异常
- 我在执行 levelOrder 函数时无法弄清楚异常终止的原因?
- 正常和异常终止C 之间的差异
- 混合使用C和C++导致异常终止
- 以std::out_of_range:vector c++类型的未捕获异常终止
- 我该如何解决它?libc++abi.dylib:以 std::invalid_argument 类型的未捕获异常终止:s
- 程序(三角形旋转)异常终止
- C/C++:在异常终止前刷新输出
- 共享库中的内部异常终止最终用户应用程序
- 调用“cvCreateCameraCapture(-1)”时异常终止
- 尝试接球投掷中的异常终止
- 当函数中静态变量的构造函数异常终止时会发生什么
- 如何自定义未捕获的异常终止行为
- 以类型为的未捕获异常终止
- close()抛出什么异常类型