Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make version with no exception support #27

Open
flexferrum opened this issue Mar 28, 2019 · 9 comments
Open

Make version with no exception support #27

flexferrum opened this issue Mar 28, 2019 · 9 comments

Comments

@flexferrum
Copy link

flexferrum commented Mar 28, 2019

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).

@martinmoene
Copy link
Owner

@DBJDBJ
Copy link

DBJDBJ commented Nov 23, 2019

Note to self: Ask Martin to have the whole nonstd exceptions free.

@flexferrum
Copy link
Author

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.

martinmoene added a commit that referenced this issue Nov 25, 2019
May need additional changes.
@martinmoene
Copy link
Owner

In version 0.4.0.

@DBJDBJ
Copy link

DBJDBJ commented Nov 14, 2020

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

HTH

@martinmoene
Copy link
Owner

martinmoene commented Nov 15, 2020

@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)

@DBJDBJ
Copy link

DBJDBJ commented Nov 15, 2020

@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 ...

@DBJDBJ
Copy link

DBJDBJ commented Nov 16, 2020

https://github.com/dbj-data/dbj-bench/blob/master/r_and_d/ms_stl_seh.md

A bit more presentable

@DBJDBJ
Copy link

DBJDBJ commented Nov 21, 2020

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".

  1. _CPPUNWIND should not be changed by users, but it should be checked for the presence of c++ exceptions
    1. besides being affected by 2 and 3 bellow it is also affected by compilation without the /EH switch
  2. _HAS_EXCEPTIONS = [ 1 | 0 ] is for users to use and that is what MST STL depends on
  3. _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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants