C++ Logo

std-proposals

Advanced search

Re: [std-proposals] RTTI in current_exception

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Tue, 10 Jan 2023 10:22:32 +0000
On Tue, Jan 10, 2023 at 12:23 AM Thiago Macieira via Std-Proposals wrote:

> > Choice 1: Deprecate the throwing of non-std::exception's.
> > Choice 2: Provide RTTI inside catch(...)
>
> Choice 3: do neither.
>
> As I said, throwing types not derived from std::exception should be
> discouraged by recommendation. The language doesn't need to enforce that
> because the *Core* language doesn't need to know anything about
> std::exception. It's just a polymorphic type like any other, to which the
> Standard *Library* assigns special meaning and we all by convention agree to
> it.


There is no distinction anymore between the core language and the
classes defined
in the standard library. I mean one of the operators in the core
language requires
a header file (i.e. typeid). And not to mention the many classes in
the standard library
that cannot be written in C++ (for example std::has_virtual_destructor).


> Realistically, the only things that will hit a catch (...) and not a
> catch (std::exception &) are foreign exceptions. There won't be a typeinfo for
> them in the first place.
>
> The proposal needs to deal with that non-hypothetical.


So maybe we need to start talking about how C++26 deals with foreign exceptions?
I see that you already broached this topic 6 years ago on the
std-discussion group:

  https://groups.google.com/a/isocpp.org/g/std-discussion/c/DLQY1iYoe_w

Perhaps we should standardise the catching of a foreign exception:

    catch ( std::alien_exception const & )
    {
    }

and maybe even go a step further to provide compatibility with a handful
of other languages, something like what I've done on GodBolt here:

        https://godbolt.org/z/Ea49PrPWo

And here's all the code copy-pasted from GodBolt:

namespace std {

struct alien_exception /* does not inherit from exception */ {
    enum class language : unsigned int { java=1u, csharp, python };
    virtual language lang(void) const noexcept = 0;
    virtual char const *what(void) const noexcept = 0;
};

namespace aliens {

  namespace java {
    struct exception : alien_exception {
        char const *getLocalizedMessage(void) const noexcept;
        char const *getMessage(void) const noexcept;
        std::stacktrace getStackTrace(void) const noexcept;
        char const *what(void) const noexcept override { return
this->getMessage(); }
        language lang(void) const noexcept override { return language::java; }
    };
  }

  namespace python {
    struct exception : alien_exception {
        char const *const *notes(void) const noexcept; /* null terminated */
        std::stacktrace traceback() const noexcept;
        char const *what(void) const noexcept override { return
this->notes()[0u]; }
        language lang(void) const noexcept override { return language::python; }
    };
  }

  namespace python {
     struct BaseException : exception {};
       struct BaseExceptionGroup : BaseException {};
       struct GeneratorExit : BaseException {};
       struct KeyboardInterrupt : BaseException {};
       struct SystemExit : BaseException {};
       struct Exception : BaseException {};
        struct ArithmeticError : Exception {};
          struct FloatingPointError : ArithmeticError {};
          struct OverflowError : ArithmeticError {};
          struct ZeroDivisionError : ArithmeticError {};
        struct AssertionError : Exception {};
        struct AttributeError : Exception {};
        struct BufferError : Exception {};
        struct EOFError : Exception {};
        struct ExceptionGroupBaseExceptionGroup : Exception {};
        struct ImportError : Exception {};
          struct ModuleNotFoundError : ImportError {};
        struct LookupError : Exception {};
          struct IndexError : LookupError {};
          struct KeyError : LookupError {};
        struct MemoryError : Exception {};
        struct NameError : Exception {};
          struct UnboundLocalError : NameError {};
        struct OSError : Exception {};
          struct BlockingIOError : OSError {};
          struct ChildProcessError : OSError {};
          struct ConnectionError : OSError {};
            struct BrokenPipeError : ConnectionError {};
            struct ConnectionAbortedError : ConnectionError {};
            struct ConnectionRefusedError : ConnectionError {};
            struct ConnectionResetError : ConnectionError {};
          struct FileExistsError : OSError {};
          struct FileNotFoundError : OSError {};
          struct InterruptedError : OSError {};
          struct IsADirectoryError : OSError {};
          struct NotADirectoryError : OSError {};
          struct PermissionError : OSError {};
          struct ProcessLookupError : OSError {};
          struct TimeoutError : OSError {};
        struct ReferenceError : Exception {};
        struct RuntimeError : Exception {};
          struct NotImplementedError : RuntimeError {};
          struct RecursionError : RuntimeError {};
        struct StopAsyncIteration : Exception {};
        struct StopIteration : Exception {};
        struct SyntaxError : Exception {};
          struct IndentationError : SyntaxError {};
             struct TabError : IndentationError {};
        struct SystemError : Exception {};
        struct TypeError : Exception {};
        struct ValueError : Exception {};
          struct UnicodeError : ValueError {};
             struct UnicodeDecodeError : UnicodeError {};
             struct UnicodeEncodeError : UnicodeError {};
             struct UnicodeTranslateError : UnicodeError {};
        struct Warning : Exception {};
           struct BytesWarning : Warning {};
           struct DeprecationWarning : Warning {};
           struct EncodingWarning : Warning {};
           struct FutureWarning : Warning {};
           struct ImportWarning : Warning {};
           struct PendingDeprecationWarning : Warning {};
           struct ResourceWarning : Warning {};
           struct RuntimeWarning : Warning {};
           struct SyntaxWarning : Warning {};
           struct UnicodeWarning : Warning {};
           struct UserWarning : Warning {};
  } // close namespace 'python'
} // close namespace 'aliens'

class forced_stack_unwind {};

} // close namespace 'std'

extern int Some_Func_In_Python_Library(void) { return 7; /* or throws
a Java exception */ }

int main(void)
{
    try { Some_Func_In_Python_Library(); }
    catch ( std::aliens::python::FloatingPointError const & )
    {
        // The specific Python exception we want to handle
    }
    catch ( std::aliens::python::exception const & )
    {
        // Any exception thrown from Python
    }
    catch ( std::alien_exception const &)
    {
        // Maybe the Python library linked with an
        // Eiffel library that threw an exception
    }
    catch ( std::forced_stack_unwind )
    {

    }
}

Received on 2023-01-10 10:22:43