3 ms·
> Exceptions opponents have devised many ways of dealing with errors in constructors. They all boil down to this pattern: myobj obj; obj.complete_initi
by amluto 2y ago
> Exceptions opponents have devised many ways of dealing with errors in constructors. They all boil down to this pattern:
myobj obj;
obj.complete_initialization();
Do they? How about the constructor-that’s-not-a-constructor pattern:
myobj::create(…);
And have that return an option or result type? This is the normal way to do this in several languages (Rust, but also plenty of functional languages), and C++ can do it too, awkwardly, using private constructors and public static helpers. (Awkward because the object may still need to exist, temporarily, in a partially constructed state outside a constructor.)
I wonder whether coroutines in C++ could pull this off without being too tedious.
- hedora 2y agoUnless you are actually handling out of memory errors and running in production with memory overcommit turned off, you probably should just panic if malloc fails. Disabling exceptions achieves this in C++. If you are trying to handle OOM, then you should at least have a big fuzz test setup that causes malloc to spuriously return null, and also set your debug builds to do this too. Good luck writing stable software that way (vs just not dynamically allocating stuff on the heap) —- everything becomes exponentially more complicated and difficult to reason about / test.
- amluto 2y agoHuh? This has nothing to do with memory failure. Imagine: class UTF8String { public: static optional<UTF8String> FromBytes(const void *buffer, size_t len); private: UTF8String(...); void *bytes; size_t length; }; UTF8String::FromBytes can fail if the input is invalid. In this particular case, it can obviously be implemented without constructing a UTF8String until it's past the point of no return. But I can imagine cases where pulling this off is awkward.
- _huayra_ 2y agoThese "factory functions" are indeed possible, but in practice I've seen the "delayed initialization" done in most places I've worked. Where I'm currently working, a common "drive-by PR" I do on others' code as I'm reading through it is the "you forgot to add the is_this_initializated? check on this method". It's not really until someone on the team has been burned by this partially-complete-but-still-validish objects gets used before Initialize() has been called and invokes very weird behavior do people get serious about this :( Though not common, this factory function method does not work for immovable types. You can't yoink these types out of the optional<T> that's returned and put them in a vector<T>, for instance.