HN2new | past | comments | ask | show | jobs | submitlogin

Handling constructor failure is one of the least valuable use cases for exceptions. Idioms for exception-free construction are straightforward and some cases will require these idioms even with exceptions.

Resource exhaustion or hardware failures are the more straightforward use cases for exceptions, but doing anything clever in those cases requires writing similar handling code as you would without exceptions.



It's actually the most useful one. It enables the creation of state invariants.


Maintaining state invariants is trivial without exceptions thrown from constructors. Just make constructors private and write a public static factory method. Allowing exceptions in constructors on the other hand creates the problem of: what should the destructor of an only partially constructed object do? It’s just unnecessary.


I think there is a misconception on your part. Formally, there is no "half-constructed" object, at least not in any way that's missing an automatic mechanism to unwind mid-way (i.e. half-deconstruct).

Each object construction is a list of N + 1 construction stages -- constructing the N subobjects (implicitly or as per the initializer list), followed by the constructor body.

The destructor has N + 1 stages too, those match exactly the constructor's stages. If there is an exception happening in any stage of the constructor, say stage E, naturally only stages 0 to E-1 get un-done (in reverse), but not E nor any later stage.

So what you have to do is imagine that all sub-objects are already constructed, and imagine there is a function that runs the constructor body and destructor body in a sequence. The constructor part could throw an exception, causing the destructor part to never run. Like any other function, it should be possible to run it without leaking anything if an exception happens. Make it "exception safe" using RAII or by being extra careful.

If you've written constructor and destructor such that they match in this way (which is, again, like you would write any other function), then will work correctly in all cases. This is a powerful concept and pretty much fool-proof. I say that as someone who has lots of concerns about the language's complexity -- including exceptions.


If you call mmap/VirtualAlloc/open/fopen in your constructor and later it throws, you will have a resource leak, because the destructor won’t clean it up.


Again, you need to make the constructor exception safe, that's just like any other function. Just imagine the constructor and destructor bodies as one combined function. (Of course don't forget the method calls in between but those should preserve the class invariant).


The problem you mention doesn't exist, since destructors are not called when a constructor throws.


If you call mmap/VirtualAlloc/open/fopen in your constructor and later it throws, you will have a resource leak, because the destructor won’t clean it up.


If you don't know how to write exception-safe code -- for which RAII is the most common idiom -- then you have exception safety issues.

I don't see how that relates to the thread, other than to say exceptions in constructors are quite fundamental.


In the domain where Misra is applied, resource exhaustion and hardware failures are totally valid scenarios that need to be processed in the same way as any other error.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: