0

Everyone seems to hate the idea - and I've been recommended to use sum_types instead. However, C++ has some "deprecated" throws(...) syntax

With this:

template<class Ret, class... E>
struct checked {
    bool threw();
    Ret get();
    std::variant<std::unique_ptr<E>...> exception();
}

One could write

int throwing() throws std::invalid_argument, std::runtime_error;

try {
    auto x = 1 + throwing();
} catch(const std::runtime_error& e){
    printlin("threw runtime error: {}", e.what());
} catch(const std::invalid_argument& e){
    printlin("threw invalid argument: {}", e.what());
}

which would compile to

checked<int, std::variant<std::invalid_argument, std::runtime_error>> throwing();

auto result = throwing();
if (result.threw()) {
    auto exception = result.exception();
    switch(exception.index()){
        case 0:
            printlin("threw invalid argument: {}", exception.get(0)->what()); break;
        case 1:
            printlin("threw runtime error: {}", exception.get(1)->what());          
    }
} else {
    auto x = 1 + reuslt.get();
}

allows for propagated checked exceptions - while still allowing one to use their beloved sum type


Could this be implemented in c++ - and would this be faster than current exceptions

Tobi Akinyemi
  • 804
  • 1
  • 8
  • 24
  • Worth a read http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0003r0.html#2.0 and also https://devblogs.microsoft.com/oldnewthing/20180928-00/?p=99855 – Richard Critten Feb 04 '21 at 23:40
  • Does this answer your question? [Why c++ use throw() keyword to indicate the function won't throw any exceptions](https://stackoverflow.com/questions/58655890/why-c-use-throw-keyword-to-indicate-the-function-wont-throw-any-exceptions) – rsjaffe Feb 04 '21 at 23:42
  • They are deprecated because they turned out to be a not so good idea. I dont understand why you think you need exception specifications in your example. "Could this be implemented" what specifically do you mean with "this" ? – 463035818_is_not_an_ai Feb 04 '21 at 23:43
  • @largest_prime_is_463035818 "this" means checked exceptions, in this manner. It wouldn't crash your app, if another type was thrown like the old checked exceptions - it would just act as a standard throw. Essentially, this wouldn't require a rewrite/rethink of exception handling - merely provide a new API for exception handling (this does the same thing people currently do with sum_types - in a nicer way) – Tobi Akinyemi Feb 04 '21 at 23:45
  • you can already throw different types of exceptions without crashing, you only have to remove the exception specification ;) After reading the answers I think I understood what you are after. I wasnt sure what you mean with "Checked exceptions" – 463035818_is_not_an_ai Feb 04 '21 at 23:51

2 Answers2

2

C++ had a broken "checked" exception system.

It required compilers to do a universal catch and terminate rather than propogate the exception, and did not check that the body of the function only threw what it said it threw. It increased costs and made programs shut down.

Real checked exceptions check the body of the function to see that it only throws what it throws, and/or that code that calls it catches it or propogates the same exception checking syntax.

Now all is not lost.

There are proposals involving a unified checked exception system with C.

Here is one: https://wg21.link/p0709r2 https://github.com/cplusplus/papers/issues/310

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • Took me a while to find this and by the time I did, I realized I'd misinterpreted the point of the question. I think it fits here as an addendum, though: [A Pragmatic Look at Exception Specifications](http://www.gotw.ca/publications/mill22.htm) – user4581301 Feb 05 '21 at 00:52
2

What happened to C++'s checked exceptions?

Nothing happened, as there never were checked exceptions in C++.

If you're referring to the removed "dynamic" exception specifications with throws(type1, type2, ...) syntax, that was quite different from checked exceptions: Checked exception is something that caller must catch (or declare to throw out). There was never such feature in C++. My experience with it in Java is that it's painful.

The removed throws specification was a promise that nothing else except the listed types would be thrown (and violating that promise will cause the program to terminate). If you indeed are referring to this and asking why they were removed, that is discussed in standards proposals such as P0003

experience of using them was less than desired, with the general consensus by the time the 1998 standard was published being, generally, to not use them. The standard library made the explicit choice to not use exception specifications apart from a handful of places where guaranteeing an empty (no-throwing) specification seemed useful. N741 gives a brief summary of the LWG thoughts at the time.

By the time C++11 was published, the feeling against exception specifications had grown, the limited real-world use generally reported negative user experience, and the language feature, renamed as dynamic exception specifications, was deprecated, (N3051). A new language feature, noexcept, was introduced to describe the important case of knowing when a function could guarantee to not throw any exceptions.

N741 is indeed, very brief on the reasoning:

This overconstrains the implementation of libraries.


Could this be implemented in c++

I don't see a reason why your checked template couldn't be implemented.

But no, there's no way to implement the throws keyword within the language. If you mean, could C++ be changed to have such feature: Perhaps. I recommend trying to implement it.

would this be faster than current exceptions

It's best not make guesses about a feature that doesn't exist yet. If you manage to implement it, compare it with current exceptions by measuring.


For what it's worth, your suggested checked type and the "would compile to" example are quite similar to std::excepted that has been proposed P0323 and has been implemented.

And your "One could write" example is quite similar to an "Possible future extensions (not proposed)" example from another proposal P0709 on page 46.

eerorika
  • 232,697
  • 12
  • 197
  • 326