Boost logo

Boost :

Subject: Re: [boost] Boost and exceptions
From: Dave Abrahams (dave_at_[hidden])
Date: 2012-06-24 09:56:12


on Sun Jun 24 2012, "Robert Ramey" <ramey-AT-rrsd.com> wrote:

> Dave Abrahams wrote:
>> on Sat Jun 23 2012, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
>
>> Like some other things we've discussed, that's essentially a C++
>> language feature. You couldn't do a plain "throw e" either, without
>> causing the slice. The only way to propagate the contents of e is
>> "throw;", which is obviously incapable of enhancing the thrown
>> exception in any way.
>>
>> The the more you pick at Emil's design and the more I check your
>> arguments, the more impressed I am with the care he took.
>
> My reaction is just the opposite
>
> even little things are a problem, The first thing I looked at was
> the documentation of BOOST_THROW_EXCEPTION(e).
>
> If this is invoked at the exception site it works. If it is invoked
> anywhere else - like a rethrow it doesn't.

IMO it is unreasonable to expect "BOOST_THROW_EXCEPTION(e)" to work
better in this regard than "throw e" does. As I wrote above, they have
the exact same issue.

> It's totally non-intuitive and a trap for users.

IMO it's totally intuitive for BOOST_THROW_EXCEPTION to follow the
pattern set by "throw." Of course it would be nice if the library
facility could be somehow more forgiving of ignorance and misuse than
"throw" is, but, well, it can't.

> There is no mention of this in the documentation.

With all due respect, from the foregoing discussion it is plain that
there are a few fairly basic things about the behavior of C++ exceptions
that you didn't understand, and that lack of understanding has colored
your expectations of the library. You also expected "throw e" to be
non-slicing. It might be very nice if the library documentation
included a tutorial on these issues, but it's unreasonable to treat it
as a defect in the library.

> And of course the whole idea that to gain benefit of a library one
> has to change the code of all the other libraries that the application
> might use is a big problem for me.

I agree absolutely. The C++ language should make it more natural and
MUCH less intrusive to do this stuff. There's always a balancing act
when you have to decide whether to proceed with implementing something
that cuts across the grain of the language. Sometimes it's not worth
the cost. As these sorts of things go, this one has a fairly low cost,
but it's not free.

> The fact that the author doesn't think this is a problem is a very
> strong suggestion to me that I'd find the library problematic to
> actually use.

It's understandable that you'd take issue with the author's attitude
toward your objections. However, I think part of the problem, for which
you might consider taking responsibility, is that your reaction to the
issue has been somewhat... intemperate and overbroad. That tends to
make other people dismissive ("he *can't* be serious!"), and with that,
any legitimate concerns tend to get swept aside.

> And this is even before I've really even looked at it. I've more than
> a little skeptical.

Quite clearly.

> And I believe that a solution could have been crafted to avoid the issues
> that I've raised but that Emil doesn't agree that these concerns are
> legimate. I know steve doesn't agree with me on this either.

Wait; there are two separate things:

1. Are your concerns legitimate?
2. Is there a design that avoids these issues?

I've seen lots of argument about #2, but not much about #1. I haven't
read everything that Emil has posted, but Steven in particular has stuck
closely to the technical stuff (#2). Re: #2, I don't see how there can
be a substantially better design for this facility either, at least with
C++ as it exists today.

> So now I would have to provide a counter example which means basically
> re-doing the original work in the right way as I see it.

Unfortunately, yes. There's no other way to support your claim about
#2.

>> I may be
>> misunderstanding, but IIUC, the "problem" that he "fixed" was that his
>> change caused already-unsupported misuses of boost::throw_exception to
>> stop compiling. It's arguable that those misuses *should* be flagged
>> with compiler errors.
>
> the original boost::throw_exception was defined as:
>
> #ifdef BOOST_NO_EXCEPTIONS
> void throw_exception( std::exception const & e ); // user defined
> #else
> template<class E>
> void throw_exception(E const & e){
> throw(e);
> }
> #endif
>
> it's hard to see how one could even define "misuse" of this - much
> less detect it.

It's trivial:

  boost::throw_exception(1)

you detect it by setting BOOST_NO_EXCEPTIONS, which causes the code to
stop compiling. A reasonable rewrite of the original
boost::throw_exception that does this detection without adding any new
functionality might be:

  #ifdef BOOST_NO_EXCEPTIONS
  void throw_exception( std::exception const & e ); // user defined
  #else
  template<class E>
  void throw_exception(E const & e){
      std::exception const& must_be_a_std_exception = e; // <=== NEW
      throw(e);
  }
  #endif

Arguably it would have gone more smoothly for Emil had he done this,
then waited a while (a whole release cycle?), and then implemented his
changes. Then nobody would have been able to complain that
Boost.Exception broke their code.

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

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