C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::typeid_except ( Paper Attached )

From: Sebastian Wittmeier <wittmeier_at_[hidden]>
Date: Mon, 4 Mar 2024 11:34:54 +0100
I think this is the right behaviour: Regardless whether the user uses no flag, /EHsc, /EHs or /EHa; and whether the user registers a  _set_se_translator() wrapper, your typeid_except (I also prefer `exception_typeid`; `_except` sounds more like except vs. noexcept) should take, what it gets. Installing by default a new  _set_se_translator( trans_func ); wrapper with changed defaults for C structured exceptions would possibly break things and would unnecessarily widen the scope of your paper. If you or Microsoft see the necessity, they would probably use a new flag, e.g. /EHt for throw exception with RTTI type information by default. Probably they won't, as currently they do not throw a C++ exception automatically, but offer to register the  _set_se_translator(); wrapper. And then the user can choose, which C++ exception is thrown.   -----Ursprüngliche Nachricht----- Von:Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]> Gesendet:Mo 04.03.2024 11:19 Betreff:Re: [std-proposals] std::typeid_except ( Paper Attached ) An:std-proposals_at_[hidden]; CC:Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>; On Sun, Mar 3, 2024 at 11:07 PM Sebastian Wittmeier wrote: > > The question is, whether "Microsoft could do it" and change the default > for C structured exceptions under C++: Existing programs and libraries > possibly rely on the current behaviour. > > It is a runtime setting per thread and not a setting per translation unit. > So changing the default for a new C++ standard version would possibly > lead to incompatibilities, when mixing standard version of TUs or > incorporating static or dynamic libraries. > > The other question is, whether changing the behaviour of C structured > exceptions is necessary at all for the proposal. I have Microsoft Visual Studio 2022 installed here on my work laptop. I compiled the following source file with:    cl /std:c++20 /EHa source_file.cpp and the executable prints out:    Caught an unknown exception    We have an valid exception_ptr    0xc0000094 Here's the code:    // compile with: /EHa    #include <exception>             // exception    #include <iomanip>               // hex, setfill, setw    #include <iostream>              // cout, endl    void DivideByZero(void)   // Throws a SEH exception    {        int x, y = 0;        x = 5 / y;    }    int main(void)    {        using std::cout, std::endl, std::hex, std::setfill, std::setw;        try        {            DivideByZero();        }        catch(std::exception const &e)        {            cout << e.what() << endl;        }        catch(...)        {            cout << "Caught an unknown exception" << endl;            auto const ep = std::current_exception();            if ( false == static_cast<bool>(ep) )            {                cout << "We have an invalid exception_ptr" << endl;                return 0;            }            cout << "We have an valid exception_ptr" << endl;            unsigned const &n = **(unsigned**)&ep;            cout << "0x" << hex << setfill('0') << setw(8u) << n << endl;        }    } So far, so good. So when you catch an SEH exception, the 'exception_ptr' is valid and you can get the SEH number from it. Now let me try a more complicated program to also get the 'type_info'. The following program is able to get the 'type_info' when you throw an intrinsic such as "throw 58.2L", but it cannot get the 'type_info' when an SEH exception is thrown. Therefore I think my proposed new function 'std::typeid_except' would have to return "typeid(void)" when it an SEH exception is caught inside a "catch(...)". // compile with: /EHa #include <exception>             // exception #include <iomanip>               // hex, setfill, setw #include <iostream>              // cout, endl #include <Windows.h> // AddVectoredExceptionHandler #include <ehdata.h>  // ThrowInfo namespace std {    namespace detail {        thread_local std::type_info const *tl_ti = &typeid(void);    }    std::type_info const &current_exception_typeid(void) noexcept    {        return *detail::tl_ti;    } } void DivideByZero(void)   // Throws a SEH exception {    int x, y = 0;    x = 5 / y; } int main(void) {    using std::cout, std::endl, std::hex, std::setfill, std::setw;    try    {        DivideByZero();    }    catch(std::exception const &e)    {        cout << e.what() << endl;    }    catch(...)    {        cout << "Caught an unknown exception" << endl;        auto const ep = std::current_exception();        if ( false == static_cast<bool>(ep) )        {            cout << "We have an invalid exception_ptr" << endl;            return 0;        }        cout << "We have an valid exception_ptr" << endl;        unsigned const &n = **(unsigned**)&ep;        cout << "SEH 0x" << hex << setfill('0') << setw(8u) << n << endl;        auto &ti = std::current_exception_typeid();        cout << "Name of type: " << ti.name() << endl;    }    cout << "==========================\n";    try    {        throw 58.2L;    }    catch(std::exception const &e)    {        cout << e.what() << endl;    }    catch(...)    {        cout << "Caught an unknown exception" << endl;        auto const ep = std::current_exception();        if ( false == static_cast<bool>(ep) )        {            cout << "We have an invalid exception_ptr" << endl;            return 0;        }        cout << "We have an valid exception_ptr" << endl;        auto const &ti = std::current_exception_typeid();        cout << "Name of type: " << ti.name() << endl;    } } namespace detail { using std::type_info; type_info const *VectoredExceptionHandler_Proper(EXCEPTION_POINTERS const *const arg) {    using std::uintptr_t;    if ( nullptr == arg ) return nullptr;    EXCEPTION_RECORD const *const pexc = arg->ExceptionRecord;    if ( nullptr == pexc ) return nullptr;    switch ( pexc->ExceptionCode )    {    case 0x40010006 /*EXCEPTION_OUTPUT_DEBUG_STRING*/:    case 0x406D1388 /*EXCEPTION_THREAD_NAME        */:        return nullptr;    }    if ( 0x19930520 /* magic number */ != pexc->ExceptionInformation[0] )        return nullptr;    if ( pexc->NumberParameters < 3u ) return nullptr;    uintptr_t const module =   (pexc->NumberParameters >= 4u)                             ? pexc->ExceptionInformation[3u]                             : 0u;    ThrowInfo const *const pthri =        static_cast<ThrowInfo const*>(            reinterpret_cast<void const*>(                static_cast<uintptr_t>(pexc->ExceptionInformation[2u])));    if ( nullptr == pthri ) return nullptr;    if ( 0 == pthri->pCatchableTypeArray ) return nullptr;    if ( 0u == (0xFFFFFFFFu & pthri->pCatchableTypeArray) ) return nullptr;    _CatchableTypeArray const *const pcarr =      static_cast<_CatchableTypeArray const *>(        reinterpret_cast<void const*>(          static_cast<uintptr_t>(module + (0xFFFFFFFFu & pthri->pCatchableTypeArray))));    if ( 0u == ( 0xFFFFFFFFu &        reinterpret_cast<uintptr_t>(pcarr->arrayOfCatchableTypes[0u])  )  )           return nullptr;    CatchableType const *const pct =      static_cast<CatchableType const*>(        reinterpret_cast<void const*>(          static_cast<uintptr_t>(module +            (0xFFFFFFFFu & reinterpret_cast<uintptr_t>(              pcarr->arrayOfCatchableTypes[0u])))));    if ( 0u == (0xFFFFFFFFu & pct->pType) ) return nullptr;    type_info const *const pti =        static_cast<type_info const *>(            reinterpret_cast<void const*>(                static_cast<uintptr_t>(module + (0xFFFFFFFFu & pct->pType))));    return pti; } long WINAPI VectoredExceptionHandler(EXCEPTION_POINTERS *const pointers) {    type_info const *const retval = VectoredExceptionHandler_Proper(pointers);    if ( nullptr == retval ) std::detail::tl_ti = &typeid(void);                        else std::detail::tl_ti = retval;    return EXCEPTION_CONTINUE_SEARCH; } void *const dummy = ::AddVectoredExceptionHandler(1u, VectoredExceptionHandler); } // close namespace 'detail' -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2024-03-04 10:34:56