簡體   English   中英

d'tor 的函數 try-block 是否應該允許處理拋出成員變量 d'tor?

[英]Should function-try-block of d'tor allow handling of throwing member-variable 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-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.
    }

是“錯誤的”相當於

~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 )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM