Clever code - kudos to potatoswatter on this one. I think that I would have to find some way around the last item though.
throw;
rethrows the active exception. It is only valid if acatch
block is on the stack. I can't recall where I came across that tidbit at but it was probably on SO in the context of some other question. The bare throw gives us access to the current exception by catching it in thechained_exception
constructor. In other words,prev
in the constructor is a reference to the exception that we are currently processing.You are correct here. This prevents double deletion.
The sentinel exception, the one thrown in
main
, should never be deleted. The one identifying attribute of this exception is that it'slink
member isNULL
.This is the part that I don't like but cannot think of an easy way around. The only visible
chained_exception
constructor can only be called when acatch
block is active. IIRC, a bare throw without an activecatch
block is a no-no. So, the workaround is to throw inmain
and put all of your code in thecatch
block.
Now, if you try this method in multi-threaded code, make sure that you understand (4) very well. You will have to replicate this in your thread entry point.