Forums before death by AOL, social media and spammers... "We can't have nice things"
|    comp.lang.c++.moderated    |    Moderated discussion of C++ superhackery    |    33,346 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 32,363 of 33,346    |
|    Thomas Richter to All    |
|    Re: Will we ever be able to throw from a    |
|    05 Jun 12 06:32:43    |
   
   From: thor@math.tu-berlin.de   
      
   { Reformatted; please limit your lines to 70 characters -mod/we }   
      
   Am 05.06.2012 11:40, schrieb Zeljko Vrba:   
      
   > I apologize for the wording, but this doesn't make sense. If you   
   > throw from the destructor then either   
   >   
   > 1) stack unwinding is not in progress, so you can catch the   
   > exception and handle the error as usual (isn't the whole point   
   > of exceptions that you can ignore WHERE it came from? -- what   
   > makes an exception thrown from a dtor different from an   
   > exception thrown from a regular method?)   
      
   Can you? What happened with the object under destruction? Apparently,   
   it is not properly destructed, otherwise there wouldn't be an   
   exception, yet you have no longer a way of accessing this object and   
   trying a different clean-up strategy.   
      
   >   
   > - or -   
   >   
   > 2) terminate() gets called -- isn't this drastic enough? (Remember   
   > that you can install terminate handler!)   
      
   True, but that's often the last resort - can one savely continue the   
   program after terminate has been called? How?   
      
   > Note that 1) also requires that your program is prepared to handle   
   > cleanup errors *along* with other errors. What is so special about   
   > cleanup errors, apart from everybody assuming that they "can't   
   > happen"?   
      
   That handling cleanup errors (and others) requires cleanup of objects.   
      
   > But if they "can't happen", a hypothetical throw() in a dtor will   
   > never be executed and all is well. If the "impossible" does happen,   
   > and your program doesn't handle it already, goto 2) above.   
      
   This actually means, however, that you should better replace throwing   
   in the destructor by an assert, or instead build an alternative   
   cleanup strategy into the destructor that can happen the error   
   locally. The problem is that you cannot delegate the handling of   
   cleanup errors as with other errors since the object that caused the   
   problem is already no longer reachable.   
      
   > My view is that exceptions are a way of reporting inability to   
   > fulfill invariants,   
      
   Are they? There are many error reporting algorithms, amongst them is   
   also assert().   
      
   > and I'm rather convinced that this is the only useful way of talking   
   > about exceptions as it also seems to be the only way of avoiding   
   > long discussions about what qualifies as exceptional condition.   
      
   If you throw an exception, the point is that there is somewhere a   
   catch() that can deal with the situation - otherwise, you wouldn't   
   throw in first place. That's quite logical. However, if by language   
   construct, you *cannot* deal with the situation since the object to   
   deal with is no longer reachable, the catch is superfluous in first   
   place. So you cannot throw.   
      
   > You can choose to report broken promises with some variant of return   
   > codes or with exceptions.   
      
   Or terminate the program, or assert(), or....   
      
   > The real question is: should destructors be used to enofrce   
   > invariants? If yes, how do you report inability to fulfill   
   > invariants? If not, what about RAII -- in this case the   
   > applicability of RAII suddenly gets *very* narrow.   
      
   I don't quite follow.   
      
   > Of course, there's also the 3rd possibility, which is the current   
   > "common wisdom": use RAII whenever convenient, ignore the   
   > possibility of breaking invariants in dtor and just continue running   
   > if invariant for some reason couldn't be fulfilled.   
      
   Is this truely the case? There are several strategies for error   
   handling in destructors right away, but exceptions aren't. This does   
   not mean that destructors aren't able to guarantee invariants. Just   
   that exceptions are not the right mean to deal with problems when   
   handling with them.   
      
   Typical example: fclose() returns a failure condition. What do you do?   
      
   Well, it depends: If I write a file to the system, a possible solution   
   would be to remove the file in question to ensure that the user never   
   sees incomplete and potentially corrupt data. When reading a file, a   
   solution would be to ignore it. If that is not satisfying, and the   
   error should be handled in a different way - well, don't put fclose()   
   into the destructor because then you still *need* the object to   
   resolve the situation, so closing and destruction are two different   
   things.   
      
   > I feel that your perspective is skewed. Destructor gives a certain   
   > promise to the *user* of the class, NOT to the class itself.   
      
   All fine, but if the class is gone, there is nothing to do about it.   
      
   > Your objection was that the exception handler doesn't have the   
   > access to the object whose destructor threw, so you can't attempt   
   > another cleanup. But note that you can use the exception object to   
   > transport some state to the handler. So if you wrap a file   
   > descriptor in a RAII-style object, you could code something like   
   > this: try { FD f("some_file"); ... } catch(FD_destruction_error&e) {   
   > ... do something with e.fd and e.errno } FD doesn't know how to   
   > handle failed close(), but the handler presumably knows what that FD   
   > represented physically and can choose some strategy of dealing with   
   > failed close (e.g., propmpting the user to clean his disk or choose   
   > another location to save their work, etc.) [C++ community seems to   
   > like talking a lot about things that "can't happen".]   
      
   Huh? Not at all. Just that the above program is flawed, and the design   
   isn't right. If you need a strategy for dealing with the failure,   
   don't put this operation into the destructor - otherwise the object   
   state for recovery is gone.   
      
   Greetings,   
    Thomas   
      
      
   --   
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
    [ comp.lang.c++.moderated. First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca