简体   繁体   English

d'tor 的函数 try-block 是否应该允许处理抛出成员变量 d'tor?

[英]Should function-try-block of d'tor allow handling of throwing member-variable d'tor?

I have a class whose destructor is noexcept(false) .我有一个类的析构函数是noexcept(false) I know it only throws under certain circumstances, and I want to use it as a member variable of a class with a noexcept destructor.我知道它只在某些情况下抛出,我想将它用作具有noexcept析构函数的类的成员变量。 From https://en.cppreference.com/w/cpp/language/function-try-block I read "Every exception thrown from any statement in the function body, or (for constructors) from any member or base constructor, or (for destructors) from any member or base destructor, transfers control to the handler-sequence the same way an exception thrown in a regular try block would."https://en.cppreference.com/w/cpp/language/function-try-block我读到“从函数体中的任何语句或(对于构造函数)任何成员或基构造函数抛出的每个异常,或(对于析构函数)从任何成员或基析构函数,将控制转移到处理程序序列,就像在常规 try 块中抛出的异常一样。” which makes me think this should be correct:这让我认为这应该是正确的:

#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) https://godbolt.org/z/ez17fx (MSVC)

My understanding of noexcept and the function-try-block on ~NonThrowingDtor() is that noexcept guarantees it won't throw (and that it does this by essentially doing try { ... } catch (...) { std::terminate(); } https://en.cppreference.com/w/cpp/language/noexcept_spec . But the function-try-block with catch (...) and no additional throw should guarantee it never throws. Clang is OK with this, but as the godbolt link shows, MSVC says我对noexcept~NonThrowingDtor()上的函数 try-block 的~NonThrowingDtor()noexcept保证它不会抛出(并且它通过本质上执行try { ... } catch (...) { std::terminate(); } https://en.cppreference.com/w/cpp/language/noexcept_spec 。但是带有catch (...)的函数 try-block 并且没有额外的 throw 应该保证它永远不会抛出。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.
    }

is "wrong" as equivalent to是“错误的”相当于

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

so simply如此简单

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

To not propagate exception, you have to use explicitly return :为了不传播异常,您必须显式使用return

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

Unfortunately, msvc still warns with this form which doesn't throw.不幸的是,msvc 仍然用这种不会抛出的形式发出警告。
(On the other side, clang/gcc don't warn for implicit (but do for explicit) throw in that case). (另一方面,在这种情况下,clang/gcc 不会警告隐式(但显式) throw )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM