Make version with no exception support
flexferrum opened this issue · 9 comments
For some special cases (and reasons) it would be perfect to have version of the nonstd::expected implementation with no exception support (like @TartanLlama version).
Note to self: deferred in Allow use with exceptions disabled, plan 11, nonstd-lite project issue 4.
Note to self: Ask Martin to have the whole nonstd
exceptions free.
Note to self: Ask Martin to have the whole
nonstd
exceptions free.
Because of nonstd::optional_lite also has an issues with compilation without exceptions enabled.
In version 0.4.0.
Thanks for 0.4.0 ...
Basically this is not how MS STL switches to no C++ exceptions builds.
// expected.hpp #55
// Control presence of exception handling (try and auto discover):
#ifndef nsel_CONFIG_NO_EXCEPTIONS
# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
# define nsel_CONFIG_NO_EXCEPTIONS 0
# else
# define nsel_CONFIG_NO_EXCEPTIONS 1
# endif
#endif
MS STL does not use _CPPUNWIND
, MS STL uses _HAS_EXCEPTIONS
; thus your code using it too will allow users mixing your stuff with MS STL while in no C++ exceptions builds:
// Control presence of exception handling (try and auto discover):
// Now nonstd and MS STL both depend on the same symbol
#ifndef nsel_CONFIG_NO_EXCEPTIONS
# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS == 1 )
# define nsel_CONFIG_NO_EXCEPTIONS 0
# else
# define nsel_CONFIG_NO_EXCEPTIONS 1
# endif
#endif
- The reasoning is explained in this issue electronicarts/EASTL#399 (comment), I did for EASTL.
- That change will also make possible using
nonstd
and MSVC (and MS STL), while using the/kernel
switch. - ATL (still very usefull) also uses the same symbol
HTH
@DBJDBJ Thanks for your input.
Wondering if the line should also contain defined(_HAS_EXCEPTIONS)
, like:
# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS != 0)
Edit:
Apparently easy to forget, according to Preprocessing directives, 15.2 Conditional inclusion the following is fine:
# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS != 0)
@martinmoene yes that is right, thanks ...
I think in the WIN32 world _HAS_EXCEPTIONS
always exists and it is 0 or 1. This is how I understand the effect of vcruntime.h
line 100. Thus this is also how MS STL is built each time whenever and wherever used.
// Depending on _HAS_EXCEPTIONS
// MS STL transforms to using SEH instead of c++ exceptions
// <vcruntime.h> #100
#ifndef _HAS_EXCEPTIONS
#ifdef _KERNEL_MODE
#define _HAS_EXCEPTIONS 0
#else
#define _HAS_EXCEPTIONS 1
#endif // _KERNEL_MODE
#endif // _HAS_EXCEPTIONS
// _CPPUNWIND not mentioned
Building nonstd
with or without the /kernel
switch, might clarify things considerably.
#include <windows.h> // must include for SEH to work
#ifndef WIN32
#error this is Windows build only
#endif // WIN32
#if _HAS_EXCEPTIONS
#error _HAS_EXCEPTIONS must not be 1 , add the /kernel switch to the cl command line
#endif
#include <vector>
#include <stdio.h>
// also would like to use
// full nonstd in here
// #include <nonstd/whatever>
/*
Caveat Emptor: how to build with /kernel switch
it is not enough to just provide /kernel switch
one has to manually remove any /EH switch
usually in windows builds /EHsc is added by default
This will not stop the build but RTTI (/GR-) has to be
also explicitly added as it is not switched off
by using the /kernel switch
*/
static void does_not_compile(void)
{
/*
error C2980: C++ exception handling is not supported with /kernel
try { throw 13; }
catch (...) {}
*/
}
int main()
{
__try {
// also would like to use
// full nonstd in here
std::vector<int> v_{ 1,2,3 };
// std::out_of_range
(void)v_.at(42);
}
__except ( EXCEPTION_EXECUTE_HANDLER /* aka 0*/) {
puts("Structured Exception from MS STL was caught");
}
return 42;
}
Kind regards ...
https://github.com/dbj-data/dbj-bench/blob/master/r_and_d/ms_stl_seh.md
A bit more presentable
I am slightly worried if I was clear enough, but it is not my fault: one, two or three symbols are made to dance to achieve one "thing".
_CPPUNWIND
should not be changed by users, but it should be checked for the presence of c++ exceptions- besides being affected by 2 and 3 bellow it is also affected by compilation without the
/EH
switch
- besides being affected by 2 and 3 bellow it is also affected by compilation without the
_HAS_EXCEPTIONS = [ 1 | 0 ]
is for users to use and that is what MST STL depends on_KERNEL_MODE
is not for users to use; its value is the effect of the/kernel
switch which also effects the value of the_HAS_EXCEPTIONS
. And in turn effects the MS STL compilation.
Thus it is a "good thing" nonstd
now depends on _HAS_EXCEPTIONS
, value of.
HTH