Hacker News new | ask | show | jobs
by iulian_r 1748 days ago
How do you handle failures in constructors without exceptions?
3 comments

In my company we do so by disallowing constructors to fail. If an object needs to be initialized with the potential of failure you need to call an init() function that returns an error code after construction.

Yes, that makes RAII basically impossible.

IMO the most important part of RAII is really the other side, "destruction is resource divestment" - and that still works. That is the main purpose of lock guards, refcounting wrappers, file objects and so on.
Why not a factory function that returns std::optional<T> instead? Or better a variant of T or error code?

The construct-then-init pattern is so annoying to deal with.

The safest & fastest way I'm aware of to use a unique_ptr factory. It involves adding an error flag to the class; the factory checks the error flag and resets the unique_ptr if it's true.
C++ constructors cannot express fallibility. Rust factory functions cannot placement-initialize (write into a pointer) an object too big to fit on the stack (aside from the perma-unstable `box` syntax, which I don't know if it even works or not). A unique_ptr factory cannot stack-allocate an object.

I don't know if it's possible to create a safe interface to fallible initialization, which is agnostic to whether the object will be constructed via return onto the stack, or onto heap memory. I'm interested to hear about proposals though (I've discussed this in the Rust community discord, but that isn't as public or concrete as a long-form article).

> C++ constructors cannot express fallibility.

No, they can. They can throw exceptions. My suggestion moves unsafe-construction onto the heap. Not ideal for a whole host of reasons, including a need to null-check the result -- but you can then move the object to the stack, and drop the unique_ptr. But if you're tying one hand behind your back, contortions will be necessary to accomplish the mundane.

You can have a named factory function returning an optional<T> (or your preferred fallible type).
Right, right... I still haven't adopted the '17 features yet.
First of all, I'd avoid exceptions in constructors, regardless of what programming language you use.