gpt4 book ai didi

c++ - 本地静态对象和异常

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:26:58 25 4
gpt4 key购买 nike

我应该如何处理局部静态对象的构造函数抛出的异常?例如我有以下代码:

class A
{
public:
A() {throw runtime_error("Ooops");}
};

void foo()
{
static A a = A();
cout << "Continue" << endl;
}

int main(void)
{
try
{
foo();
}
catch(...)
{
}
foo(); // Prints continue
return 0;
}

据我了解,在第二次调用 foo 方法的情况下,对象 a 被视为完全构造的对象,并且不调用构造函数。 (此外,由于未调用第一个异常抛出,似乎 a 的析构函数)

最佳答案

如果这是真的,那就是编译器错误。

(但是,VTT claims that this code produces the expected result with Visual Studio 2015,所以我建议仔细检查您的结果。)

这是标准规定的行为:

[C++14: 6.7/4]: The zero-initialization (8.5) of all block-scope variables with static storage duration (3.7.1) or thread storage duration (3.7.2) is performed before any other initialization takes place. Constant initialization (3.6.2) of a block-scope entity with static storage duration, if applicable, is performed before its block is first entered. An implementation is permitted to perform early initialization of other block-scope variables with static or thread storage duration under the same conditions that an implementation is permitted to statically initialize a variable with static or thread storage duration in namespace scope (3.6.2). Otherwise such a variable is initialized the first time control passes through its declaration; such a variable 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 enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization. If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined. [..]

GCC 6.3.0 correctly attempts to reconstruct the A (因此再次抛出)。


More over, it seems like destructor of a due first exception throwing is not called

不,不会的。您无法销毁一开始从未成功创建的对象。

[C++14: 15.2/2]: An object of any storage duration whose initialization or destruction is terminated by an exception will have destructors executed for all of its fully constructed subobjects (excluding the variant members of a union-like class), that is, for subobjects for which the principal constructor (12.6.2) has completed execution and the destructor has not yet begun execution. Similarly, if the non-delegating constructor for an object has completed execution and a delegating constructor for that object exits with an exception, the object’s destructor will be invoked. If the object was allocated in a new-expression, the matching deallocation function (3.7.4.2, 5.3.4, 12.5), if any, is called to free the storage occupied by the object.


顺便说一句,这并不能解决问题,但您应该只写:

static A a;

临时文件的复制初始化是没有意义的。

关于c++ - 本地静态对象和异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43609186/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com