The constructor example is an interesting one. A Go constructor is just a function such as `func NewMyObject(someParam string) (*MyObject, error)`, it is possible and not that uncommon to return an error in addition to the instantiated object, for example if there is some check on the parameter (an example I have in mind is http.NewRequest https://golang.org/pkg/net/http/#NewRequest).
How do people deal with constructor errors in the C++ world? I have never seen C++ code where the constructor call is wrapped in with an exception handler. I would guess that's done by creation an addition function "make_my_object"? But then what is its signature? Or is an exception handler used in that case?
If I create several objects and then one of them fails, the ones that succeeded get destructed in reverse order, and then my callers get the exception that killed me. I don't need a handler unless I know what to do about it or I'm doing something weird that doesn't work with RAII. And I can't even try to use an object that didn't properly initialize.
> I have never seen C++ code where the constructor call is wrapped in with an exception handler.
The point of exceptions is not to wrap every call that can throw but instead to let them bubble up to have them be handled where it makes most sense - a large amount of software only needs to show an error dialog to the user and asks the user to save / exit, or log a message somewhere (so a single `catch` at the top of your event loop).
Only when you know for a fact that a subsystem can actually handle a specific case of error more intelligently, then you add exception handling there.
>How do people deal with constructor errors in the C++ world? I have never seen C++ code where the constructor call is wrapped in with an exception handler.
There are about 200 different ways to be honest, stemming from the unfortunate situation that the most common advice, "use exceptions in exceptional situations", is actively harmful.
Let's take a "Connection" class for example. You'd initialize it with an IpEndpoint, or something to that effect. Some people think "well I'm writing a download script so if I can't connect the script can't continue, so that is exceptional" - so they throw an exception in the constructor and catch it somewhere in main. Other people are writing something more complicated and they think "being unable to establish a connection is normal, I'll just make a factory function for this and wrap the Connection constructor". Which leads to completely different paradigms in the same situation but with different environments - and those two decisions are both good, there are tons of decisions that aren't!
This is compounded by the fact that the C++ standard library only uses 2 kinds of resources: Memory and Files. And they use different kinds of error handling. Well, memory allocation always throws (at least it's consistent here), but the iostream error handling is, uh, interesting? Streams don't throw by default, however you can enable them to throw at runtime, but they also store their error state inside. It's a mess really.
Oh and also the std::logic_error exists and gets thrown by standard library functions, but a lot of advice around exceptions says that you're not supposed to use exceptions for programming errors, that should be handled by assertions.
And then there are of course people who just disable exceptions. Some disable exceptions but still use the standard library and just kind of hope that everything will still work?
So yeah, it's a mess. That's partly why proposals like this would help - if you can make the actual throwing of exceptions cheap, the advice of "use exceptions for exceptional situations" goes away instead becomes "use exceptions for every kind of error handling". Which would be much more consistent. And people wouldn't have an excuse to disable exceptions anymore, at least in the long run.
> And then there are of course people who just disable exceptions. Some disable exceptions but still use the standard library and just kind of hope that everything will still work?
No, there are features in most of the standard library that allow you to confirm that an object is in a state where it won't throw an exception, and you use those. For example, with std::map you can check the return of find() against end() to determine whether you can safely access the second element of the tuple. So you would do that before you access the tuple.
And you would generally write your own classes to either crash the process quickly or fail gracefully on construction. Basically you have to manage the shutdown of your process when you encounter exceptional situations in the constructor.
You can also count on any "exception" that is thrown with no-exceptions to result in an immediate crash.
> Some disable exceptions but still use the standard library and just kind of hope that everything will still work?
It's not like the errors are just ignored then. The program just aborts instead of unwinding stacks. And all the APIs you care to use have defensive ways to use them. For instance, you can check if a vector is empty before accessing element zero.
How do people deal with constructor errors in the C++ world? I have never seen C++ code where the constructor call is wrapped in with an exception handler. I would guess that's done by creation an addition function "make_my_object"? But then what is its signature? Or is an exception handler used in that case?