d'tor 的函数尝试块应该允许处理抛出成员变量 d'tor 吗?



我有一个类的析构函数是noexcept(false)。我知道它只在特定情况下抛出,并且我想将它用作具有noexcept析构函数的类的成员变量。从…起https://en.cppreference.com/w/cpp/language/function-try-block我读了";从函数体中的任何语句、(对于构造函数(从任何成员或基构造函数、(对于析构函数(从任意成员或基析构函数抛出的每个异常,都会像在常规try块中抛出异常一样,将控制权转移到处理程序序列"这让我认为这应该是正确的:

#include <exception>
class ConditionallyThrowingDtor {
public:
bool willThrow = true;
ConditionallyThrowingDtor() = default;
~ConditionallyThrowingDtor() noexcept(false) {
if (willThrow) {
throw std::exception();
}
}
};

class NonThrowingDtor {
public:
ConditionallyThrowingDtor x;
~NonThrowingDtor() noexcept try {
x.willThrow = false;
} catch (...) { 
// Ignore because we know it will never happen.
}
};

int main() {
// ConditionallyThrowingDtor y; // Throws on destruction as expected.
NonThrowingDtor x;
}

https://godbolt.org/z/ez17fx(MSVC(

我对noexcept~NonThrowingDtor()上的函数try块的理解是,noexcept保证它不会抛出(并且它本质上是通过执行try { ... } catch (...) { std::terminate(); }来实现的https://en.cppreference.com/w/cpp/language/noexcept_spec.但是带有catch (...)并且没有额外抛出的函数try块应该保证它永远不会抛出。Clang对此表示同意,但正如godbolt链接所示,MSVC表示

<source>(23): warning C4297: 'NonThrowingDtor::~NonThrowingDtor': function assumed not to throw an exception but does
<source>(23): note: destructor or deallocator has a (possibly implicit) non-throwing exception specification
~NonThrowingDtor() noexcept try {
x.willThrow = false;
} catch (...) { 
// Ignore because we know it will never happen.
}

是";错误的";相当于

~NonThrowingDtor() noexcept try {
x.willThrow = false;
} catch (...) {
throw;
}

所以简单的

~NonThrowingDtor() noexcept
{
x.willThrow = false;
}

为了不传播异常,您必须显式使用return:

~NonThrowingDtor() noexcept try {
x.willThrow = false;
} catch (...) { 
return; // Required to not propagate exception.
}

不幸的是,msvc仍然用这个不抛出的表单进行警告
(另一方面,clang/gcc在这种情况下不会对隐式发出警告(但对显式(throw发出警告(。

相关内容

  • 没有找到相关文章

最新更新