On Wednesday 15 June 2011, Emil Dotchevski wrote:
On Tue, Jun 14, 2011 at 4:00 PM, Michael Schuerig
wrote: On Wednesday 15 June 2011, Emil Dotchevski wrote:
Michael,
You're right, the boost::current_exception function is only valid within a try block.
The issue you're raising has to do with the postconditions of operator<<. Its current semantics guarantee that upon return the error info is successfully stored in the exception object. This means that when you catch an exception, you can rely on certain error info to be present:
catch( file_read_error & e ) { assert(get_error_info
(e)!=0); std::cerr << "Error reading " << *get_error_info (e); } Without this guarantee, the catch site would be required to deal with any exception even if it has no error info in it.
Emil,
thanks for your explanation. Unfortunately, I don't understand it. I do understand that e << errinfo_file_name(fn), if successful at all (i.e., it doesn't throw itself) guarantees that the respective info is present in e. However, this is a dynamic property, I don't see any static reason why it must be true for every file_read_error. So, in principle, a catch site for that exception would have to take into account that this info might be missing. Am I missing something?
The postcondition in op<< allows the programmer to make a design decision that any and all file_read_error exceptions reaching a particular catch site in the program will be guaranteed to have a file name in them, and to treat the absence of a file name as a logic error (that is, a bug, hence the assert in my example.)
This is similar to passing something to an exception type's constructor: it'll throw (something else) if it failed to construct, right? The semantics of op<< simply extend this behavior to the case when you stuff something in the exception object at a later time.
Is this a correct paraphrase: op<< either adds additional info to an exception or it raises another exception indicating its failure.
If you are to add error info to exception objects in destructors, this guarantee can not hold.
I'm not sure I understand this either. If file_read_error can be thrown without initially having an errinfo_file_name and this info is only added during unwinding higher up the call stack, then why does it make a difference if it is in a catch block or in a destructor (ignoring for a moment that calling current_exception isn't legal there)?
You're right that it doesn't make a difference, provided that you don't choose to treat the absence of certain error info as a bug. The point is that if you always add error info in destructors, that choice is not available and you must be able to deal with any exception only knowing its type.
Let's see. When I catch one exception and while I add information to it, a new exception is thrown, it is this new exception that will propagate up the call stack. By contrast, when a destructor is called due to an exception and the code in the destructor does something that throws another exception, this causes program termination. -- Is that it? Michael -- Michael Schuerig mailto:michael@schuerig.de http://www.schuerig.de/michael/