Live data from Hacker News

C++ Exceptions: Under the Hood (2013)

monkeywritescode.blogspot.com

51–60 of 116 posts

Re: C++ Exceptions: Under the Hood (2013)

#51
post #39
post #26

Earlier quoted context omitted.

Can you describe your ideal error handling mechanisms? Or at least other mechanisms that feel more correct?

I would go with the Erlang approach. Just die FFS. Let the process monitor restart you if you deserve to live.

That only makes sense if units of your code run in a loop and communicate asynchronously :). But, if you want a simple supervisor pattern in C++, then... try/catch block is your supervisor, exceptions are how your process dies. Consider:

  template
  auto CallWithSupervision(Fn fn) -> decltype(fn()) {
    // supervision loop
    // configure conditions as needed
    while(true) {
      try {
        return fn();
      }
      catch(std::exception& e) {
        // log failure details
      }
      catch(...) {
        // optional: exceptions out of handled set?
        // kill supervisor.
        throw;
      }
    }
  }

  //elsewhere
  CallWithSupervision([relevant=state,&nd=captures]() { return Client(relevant, nd); });
Modify as you see fit. It's the simplest, synchronous Erlang supervisor, in C++. And it will already work with your code - exception handling is very composable this way.

Re: C++ Exceptions: Under the Hood (2013)

#52
post #15

Earlier quoted context omitted.

What do you think of languages that use sum types for error handling, but can still unwind in a few scenarios? Reasonnable compromise, or should we get rid of all unwinding always? And if so, do we abort() or do we ask users to handle any and all possible errors.

I've read the proposals for it. It certainly looks good, yet exception handling looked good 30 years ago, too. I haven't used sum types myself, and often it takes years to discern whether things are really good ideas or not. What I personally use is the "poisoning" technique. This involves marking an object as being in an error state, much like a floating point value can be in a NaN state. Any operation on a poisoned…

I'm experimenting with a solution in C3 that has this behaviour. I don't have a sum type as such, but the binding acts as one. I call the binding a "failable".

    int! a = getMayError();
    // a is now either an int, or contains an error value.

    // foo(a) is only conditionally invoked.
    int! b = foo(a);

    // The above works as if it was written:
    // int! b = "if a has error" ? "the error of a" : foo("real value of a");

    // A single if-catch with return will implicitly unwrap:
    if (catch err = b) {
       /* handle errors */
       return;
    }
    /* b is unwrapped implicitly from here on and is treated as int */

    if (try int x = a) {
       /* conditionally execute if a isn't an error */
    }
I think this is kind of formalizing the poison technique but external from the call (that is, "foo" does not need to know about "failables" or return one, the call is skipped on the caller side). Here are some more examples: http://www.c3-lang.org/errorhandling/

I'd be interested in hearing what you think about this (experimental) solution Walter.

Re: C++ Exceptions: Under the Hood (2013)

#53

Working with and implementing C++ exceptions for 30 years now, including implementing exception handling for Windows, DOS extenders, and Posix (all very different), and then re-implementing them for D, I have sadly come to the conclusion that exceptions are a giant mistake. 1. they are very hard to understand all the way down 2. they are largely undocumented in how they're implemented 3. they are slow when thrown 4.…

I have quit using exceptions in my own code, making everything 'nothrow'.

Assuming not all code you use is your own, how does this work in combination with other code (like the STL) which is not nothrow?

Re: C++ Exceptions: Under the Hood (2013)

#54

Working with and implementing C++ exceptions for 30 years now, including implementing exception handling for Windows, DOS extenders, and Posix (all very different), and then re-implementing them for D, I have sadly come to the conclusion that exceptions are a giant mistake. 1. they are very hard to understand all the way down 2. they are largely undocumented in how they're implemented 3. they are slow when thrown 4.…

+1 plain old return error codes and the related modern status codes are the way to go. Lots of people say this is more work. I would your comment does a good job explaining why that work is immensely useful.

Re: C++ Exceptions: Under the Hood (2013)

#56

Working with and implementing C++ exceptions for 30 years now, including implementing exception handling for Windows, DOS extenders, and Posix (all very different), and then re-implementing them for D, I have sadly come to the conclusion that exceptions are a giant mistake. 1. they are very hard to understand all the way down 2. they are largely undocumented in how they're implemented 3. they are slow when thrown 4.…

Don't you need exceptions though? How do you terminate arbitrary operations without exceptions? Like say you call an algorithm (like std::sort) and during a callback (e.g. in the comparator) you decide to cancel the operation (perhaps user-requested). With exceptions it's easy; you just throw an exception and then catch it. No need to touch or even know the intermediate callers. But without exceptions what do you do?…

I agree that a modern high-level programming language model needs an ergonomic error model. But C++ exceptions are not the only way to go. You can have error model that have similar (or even better ergonomy) than C++ while not having any of the drawbacks (like extremely complicated runtime stack, slow exception handling, messed up control flow etc.). Basically, in my personal opinion, any error handling that involves automatic stack unwinding is a failure.

Re: C++ Exceptions: Under the Hood (2013)

#57
post #9
post #3

Under the hood of GCC specifically.

That's the article I used when I implemented exceptions in an LLVM-based compiler, so it's applicable to more than just GCC.

Is your work public? If my article was useful, I'd love to have a look at what you did!

Re: C++ Exceptions: Under the Hood (2013)

#58

[2013]ish if I remember. Also note the ABI for C++ exceptions followed by G++ et al is actually documented as part of the Itanium C++ ABI : https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html

According to GitHub, published in February 2013, written during 2012. I feel old now.

Re: C++ Exceptions: Under the Hood (2013)

#59
Author here; worth noting this article was written a decade ago, and while the concepts it describes are probably still useful (or so I'm told) the text is starting to show its age. Most notably, the examples are completely broken for x86-64, as I didn't have a 64bit processor when writing this.

Re: C++ Exceptions: Under the Hood (2013)

#60

Working with and implementing C++ exceptions for 30 years now, including implementing exception handling for Windows, DOS extenders, and Posix (all very different), and then re-implementing them for D, I have sadly come to the conclusion that exceptions are a giant mistake. 1. they are very hard to understand all the way down 2. they are largely undocumented in how they're implemented 3. they are slow when thrown 4.…

On the other hand

() they solve a handful of use-cases really really well.

() if you are writing relatively decent C++, most code is pretty much exception safe already

() lots of abstractions are dangerous when mis-used

() they are sufficiently low cost that they almost never show up in the fairly extensive perf profiling I do on a large real-world application (LibreOffice). And LibreOffice throws exceptions __a lot__

(*) Except for toolchain writers, nobody cares how they are implemented

Post reply on HN