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 ¤t_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