Boost logo

Boost :

From: David Abrahams (abrahams_at_[hidden])
Date: 2001-04-11 17:08:40


----- Original Message -----
From: <williamkempf_at_[hidden]>

> C++ platforms (MSVC) that throw exceptions when an assertion fires?
> Some alternative library assertion packages may do this, but none
> that come with MSVC throw exceptions. I was speaking of other
> languages here.

What does this program do with msvc?

include <cassert>
#include <iostream>

int main() {
    try {
        assert(0);
    }
    catch(...) {
        std::cout << "hi there" << std::endl;
    }
    return 0;
}

Try compiling it as follows:
    cl /MLd /GX /EHa foo.cpp

> In any event, the JIT debugger handles exceptions as easily as it
> does assertions, dropping you into the code at the point where the
> exception was thrown. So I don't know what you're trying to say here.

See above.

> > Other languages have different exception models, so its hard to
> make a case
> > about C++ exception use policy on that basis. For example, I would
> have no
> > serious objections to throwing an exception from assert() if the
> exception
> > could carry a snapshot of the program state (before unwinding) with
> it. This
> > sort of thing is possible with LISP systems.
>
> It's possible with C++ as well. There's nothing in the standard
> preventing this that I can see. Granted, it's not required either,
> which may be what you're getting at, but it's also not required for
> an assertion to be able to give you this type of information either.

That's right. Of course there are differences between theory and practice.
In practice, C++ exceptions don't do this (and there's a good reason - it
would be way too expensive), but sometimes assertions do.

Another note: other languages have different error models. For example,
interpreted languages like LISP, Java, and pure Python should never crash,
no matter what bugs a user puts in his program. In principle, it should be
possible to avoid anything like unpredictable behavior (although I think the
latter two fail to acheive this goal due to poor specification). The price
paid for this kind of security is, of course, speed. No real C++
implementation is willing to accept this performance hit, so there are
plenty of ways to crash a program. I think this leads to a different
programming model. For example, in Python, iteration through a sequence is
terminated with an IndexError exception. It isn't incorrect to index off the
end of a Python sequence - it happens all the time. We wouldn't do that in
C++, but not just because of the performance problem: we have a different
culture, a different way of looking at program correctness.

> > One final point:
> >
> > if your function is documented to throw under condition ~X, then X
> is not a
> > really precondition for your function: the behavior under ~X should
> be
> > well-defined. I don't see any point in saying "f() requires X, but
> if ~X, it
> > will throw".
> >
> > If your function is documented to require X, it is allowed to
> throw, assert,
> > or do anything else it likes under condition ~X. Whether or not
> throwing is
> > advisable can be taken on a case-by-case basis. In some
> applications where
> > recoverability is critical, it may make sense to assert in debug
> builds but
> > throw in release builds.
>
> ~X == Y is always a valid possible boolean equivalancy, so I don't
> see how this designation can be used.

I never mentioned Y. I don't understand what you're getting at.

> > I don't think it would be fair to say that I violate my own rules:
> I'm
> > saying it's a choice you have to think about. There are tradeoffs.
> Not every
> > programming decision can be made by prescription.
>
> I didn't single out any one person when I said "they" break their own
> rules. By your own admission here you don't have rules but instead
> have what I'd consider loose guidelines.

They're not really as loose as they may seem. I pretty much always assert
invariants and preconditions. I'm just unwilling to pass judgement against
someone who thinks they stand a better chance of recovery in a
mission-critical application by turning all precondition violations into
exceptions for the shipping product. IMO, a precondition violation almost
always means some program invariant is broken, so recovery is unlikely.
These people are gambling... who am I to tell them how to place their bets?

> Every time this subject has
> come up, however, the arguments always state hard and fast rules. To
> further complicate matters, even if you take these rules as loose
> guidelines instead, every person seems to have their own set.

Maybe so.

> I've
> never seen this topic come up where any kind of concensus is
> reached. I'm truly at a loss to understand when and when not to use
> exceptions.

I guess you'll just need to sort through the arguments and see which ones
ring true for you, then. Wish I could offer something more/better...

-Dave


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk