Prev: CRTP question
Next: BinaryPredicate Question
From: Lance Diduck on 13 Jan 2007 16:01 sanelz(a)gmail.com wrote: > I quickly scanned, and IMHO Account sample with assertions, at least > for me, > looks much better. Reasons? > > People often just skim documentation, and line with "this can throw" is > probably > the last thing they will notice; so forgetting try{}catch pair is > often. > > Sanel I guess I should note also, to condense what Sutter expands on in Exceptional C++, that user code should look like this: try{ //First, perform any operations that could throw, // but make no *observable* state change foo(); //could throw, but do not perform //any observable state changes (eg validate input) bar(); //could throw,but does not perform //any observable state changes (eg lookup data) baz(); //could throw,but does not perform // any observable state changes // (eg prepare SQL statement or message) // now that foo, bar and baz have succeeded // perform observable state change boom(); // does not throw, performs // observable state change, eg send message or //make DB commit, refresh screen catch(..){ //Could not perform operation due to x } //operation succeeded So the only documentation that a user needs to be aware of is not "Could it throw" but rather "is it guaranteed not to?" There are typically far fewer instances of the latter to keep up with. The only program failure point is if in fact boom() DID have an error when it shouldn't. That usually mean you have a system error. Of course, if a user entirely leaves out the try /catch block, his system would like not make past the first unit test. I have never seen this to be a problem in shops that must produce fault-tolerant ("business critical") systems. Otherwise, if you are doing something in this style bool except =false; try{ foo();catch(...){ except =true; } if(!except) try{ bar();catch(){except =true; } if(!except) try{ baz();catch(){except =true; } if(!except) boom(); Then whats the point?? May as well use return codes. Terminating Assertions?? The programs I write can't core dump just because someone on the team made a mistake or it received bad input that would cause an assertion or undefined behaviour. Assertions are nice for small unit tests and you are in a development enviroment that launches your debugger with call stack intact. But production systems? MT systems? Distributed systems? Terminating assertions, and their close cousin trace logs, are a solution worse than the problem. A good example are the Boost libraries, which normally use assertion in lieu of exceptions. Boost is a number of loosely collected independent libraries, the majority developed on PC platforms where such convienent IDE's abound. Move off of that into systems that must work in a radically different enviroment (i.e. business operations on distributed server) and exceptions quickly become de rigeur. I simply took some boost libs, change the asserts to throws (for example, in the shared_ptr class where is may deference a null pointer) and things work much better *for our enviroment* But note that you can always replace an exception with a terminating assertion, but vice versa is NOT true. This is easy to see: void foo1(int x){ int* p=new int;//just for demo assert(x!=0); delete p; } Works fine with assertions, but with exceptions. no can do. Boost is well written, so that in their case you can in fact replace one with the other. But I have seen libraries, even written by supposed C++ experts, where they were not interchangable, because the author many indeed have been a C++ guru when exceptions were not prevalent, but exceptions require different skill set that non-exception code, as everybody first coping with them is painfully aware. So Caveat Emptor!! -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |