From: Lance Diduck on
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! ]

First  |  Prev  | 
Pages: 1 2 3
Prev: CRTP question
Next: BinaryPredicate Question