[boost] Boost and exceptions

1,062 views
Skip to first unread message

Dirk Ulrich

unread,
Jun 17, 2012, 6:45:50 AM6/17/12
to bo...@lists.boost.org
Dear all,

when looking at Boost as a whole its obvious that it uses C++ exceptions to
report exceptional conditions because its the C++ way of doing it and it has
to interact with the C++ standard library. On the other hand it seems also
obvious that some libraries (Boost.Units, Boost.MPL, etc.) do probably not
use C++ exceptions at all since they are pure compile time libraries or
provide services which do not have exceptional cases.

I am working on a C++ based project which forbids the usage of C++ exceptions
but it is still preferable to use Boost libraries at least the ones which do
not make use of C++ exceptions at all. I am especially interested in using
Boost.Units and Boost.Math.

Which of Boost libraries do NOT make use of C++ exceptions (i did not find
such a list but maybe its already available somewhere)?

What would it take to use these libraries as a stand-alone "minimal" Boost
library?

Thanks


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Mathias Gaunard

unread,
Jun 18, 2012, 5:25:36 AM6/18/12
to bo...@lists.boost.org
On 17/06/2012 12:45, Dirk Ulrich wrote:

> I am working on a C++ based project which forbids the usage of C++ exceptions
> but it is still preferable to use Boost libraries at least the ones which do
> not make use of C++ exceptions at all.

All Boost libraries should work with exceptions disabled, with
potentially limited functionality. If that is not the case, it's
probably a library-specific bug that should be reported.

If exceptions are disabled, Boost will call
boost::throw_exception(std::exception const&), which must be defined by
the user.

Vicente Botet

unread,
Jun 18, 2012, 7:24:23 AM6/18/12
to bo...@lists.boost.org

Mathias Gaunard-2 wrote
>
> On 17/06/2012 12:45, Dirk Ulrich wrote:
>
>> I am working on a C++ based project which forbids the usage of C++
>> exceptions
>> but it is still preferable to use Boost libraries at least the ones which
>> do
>> not make use of C++ exceptions at all.
>
> All Boost libraries should work with exceptions disabled, with
> potentially limited functionality. If that is not the case, it's
> probably a library-specific bug that should be reported.
>
>

Hi,

I don't see this as a bug but as a nice to have feature. In addition, for
some libraries, the subset that could work with exceptions disabled could be
minimal.

I agree however that a list of libraries that works with exceptions disabled
should be built as well as the ones with no-rtti. Anyway, we need some
testers that will run the regression test with the specific options. Any
volunteers?

Best,
Vicente

--
View this message in context: http://boost.2283326.n4.nabble.com/Boost-and-exceptions-tp4631441p4631449.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Ulrich,

unread,
Jun 18, 2012, 7:35:12 AM6/18/12
to bo...@lists.boost.org
I understand that Boost provides a possibility to disable the usage of C++
exceptions and instead it provides a callback (boost::throw_exception()) which
clients can implement to catch any
exception thrown.

But that's not what i was looking for. I was more looking for a list of
libraries which have kind of
a "noexcept" guarantee (which would not even call boost::throw_exception())
because their service is either fully at compile
time or simply has no exceptional cases (as i would expect from Boost.Units for
example).

Furthermore i wonder what the implementation requirements for implementation
boost::throw_exception() are (sorry, i could not find
any documentation yet). When looking at the Boost code it seems that it is not
expected for boost:throw_exception() to return
but to abort the program immediately. Is that correct?

I also wonder how Boost handles allocation using new() in case of exceptions
being disabled. In this case the new() operator is expected
to return a NULL pointer instead of throw std::bad_alloc but i could not find
code that tests pointers against NULL at places where allocations
were done (i saw that Boost makes use of allocators instead of using plain new()
but that should probably be the same).

Emil Dotchevski

unread,
Jun 18, 2012, 3:29:27 PM6/18/12
to bo...@lists.boost.org
On Mon, Jun 18, 2012 at 4:35 AM, Ulrich, <dir...@yahoo.de> wrote:

> I understand that Boost provides a possibility to disable the usage of
> C++
> exceptions and instead it provides a callback (boost::throw_exception())
> which
> clients can implement to catch any
> exception thrown.
>
> But that's not what i was looking for. I was more looking for a list of
> libraries which have kind of
> a "noexcept" guarantee (which would not even call boost::throw_exception())
> because their service is either fully at compile
> time or simply has no exceptional cases (as i would expect from
> Boost.Units for
> example).
>

Overall you're probably out of luck. As far as exceptions are concerned,
the only requirement that exists for Boost Libraries is that they throw by
calling boost::throw_exception, but this doesn't guarantee usability. It is
just a mechanism to enable Boost authors to enforce postconditions, that
is, to protect their own code from the effects of disabled exception
handling.

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Robert Ramey

unread,
Jun 18, 2012, 4:52:13 PM6/18/12
to bo...@lists.boost.org
Emil Dotchevski wrote:
> On Mon, Jun 18, 2012 at 4:35 AM, Ulrich, <dir...@yahoo.de> wrote:

> the only requirement that exists for Boost Libraries is that they
> throw by calling boost::throw_exception, ...

since when is this a requirement?

Robert Ramey

Emil Dotchevski

unread,
Jun 18, 2012, 4:04:07 PM6/18/12
to bo...@lists.boost.org
On Mon, Jun 18, 2012 at 1:52 PM, Robert Ramey <ra...@rrsd.com> wrote:

> Emil Dotchevski wrote:
> > On Mon, Jun 18, 2012 at 4:35 AM, Ulrich, <dir...@yahoo.de> wrote:
>
> > the only requirement that exists for Boost Libraries is that they
> > throw by calling boost::throw_exception, ...
>
> since when is this a requirement?
>

I meant it is a requirement if a library that throws exceptions supports
BOOST_NO_EXCEPTIONS builds. AFAIK libraries aren't required required to
support BOOST_NO_EXCEPTIONS.

Robert Ramey

unread,
Jun 18, 2012, 6:56:44 PM6/18/12
to bo...@lists.boost.org
Emil Dotchevski wrote:
> On Mon, Jun 18, 2012 at 1:52 PM, Robert Ramey <ra...@rrsd.com> wrote:
>
>> Emil Dotchevski wrote:
>>> On Mon, Jun 18, 2012 at 4:35 AM, Ulrich, <dir...@yahoo.de> wrote:
>>
>>> the only requirement that exists for Boost Libraries is that they
>>> throw by calling boost::throw_exception, ...
>>
>> since when is this a requirement?
>>
>
> I meant it is a requirement if a library that throws exceptions
> supports BOOST_NO_EXCEPTIONS builds.

Hmm - that sentence doesn't quite make sense for me. I'm supposing that
it means:

"if a library throws exceptions it is required to invoke
boost::throw_exception"

Assuming my understanding is correct my question is:

since when is THIS a requirement?

Robert Ramey

Emil Dotchevski

unread,
Jun 18, 2012, 6:34:32 PM6/18/12
to bo...@lists.boost.org
On Mon, Jun 18, 2012 at 3:56 PM, Robert Ramey <ra...@rrsd.com> wrote:

> Emil Dotchevski wrote:
> > On Mon, Jun 18, 2012 at 1:52 PM, Robert Ramey <ra...@rrsd.com> wrote:
> >
> >> Emil Dotchevski wrote:
> >>> On Mon, Jun 18, 2012 at 4:35 AM, Ulrich, <dir...@yahoo.de> wrote:
> >>
> >>> the only requirement that exists for Boost Libraries is that they
> >>> throw by calling boost::throw_exception, ...
> >>
> >> since when is this a requirement?
> >>
> >
> > I meant it is a requirement if a library that throws exceptions
> > supports BOOST_NO_EXCEPTIONS builds.
>
> Hmm - that sentence doesn't quite make sense for me. I'm supposing that
> it means:
>
> "if a library throws exceptions it is required to invoke
> boost::throw_exception"
>

No, it means that if a library that throws exceptions supports
BOOST_NO_EXCEPTIONS builds, it is required to use boost::throw_exception to
throw. I know you have your own reasons to use a parallel implementation of
boost::throw_exception, that's fine.

Robert Ramey

unread,
Jun 19, 2012, 12:55:14 AM6/19/12
to bo...@lists.boost.org
Emil Dotchevski wrote:
> On Mon, Jun 18, 2012 at 3:56 PM, Robert Ramey <ra...@rrsd.com> wrote:
>
>> Emil Dotchevski wrote:
>>> On Mon, Jun 18, 2012 at 1:52 PM, Robert Ramey <ra...@rrsd.com>
>>> wrote:
>>>
>>>> Emil Dotchevski wrote:
>>>>> On Mon, Jun 18, 2012 at 4:35 AM, Ulrich, <dir...@yahoo.de> wrote:
>>>>
>>>>> the only requirement that exists for Boost Libraries is that they
>>>>> throw by calling boost::throw_exception, ...
>>>>
>>>> since when is this a requirement?
>>>>
>>>
>>> I meant it is a requirement if a library that throws exceptions
>>> supports BOOST_NO_EXCEPTIONS builds.
>>
>> Hmm - that sentence doesn't quite make sense for me. I'm supposing
>> that it means:
>>
>> "if a library throws exceptions it is required to invoke
>> boost::throw_exception"
>>
>
> No, it means that if a library that throws exceptions supports
> BOOST_NO_EXCEPTIONS builds, it is required to use
> boost::throw_exception to throw.

Well, this is certainly news to me. I had always understood that
BOOST_NO_EXCEPTIONS was defined for compilers which
do not support the throw/catch statements. This posting starts
a thread which http://lists.boost.org/Archives/boost/2003/09/53399.php
which seems to end with the statement

"No, we're talking about compilers that don't support C++ exceptions at all
(embedded Visual C++ for example) - hence no unwinding no matter what else
may be going on. And yes it was badly worded :-) "

At some point, the definition of BOOST_NO_EXCEPTION was
hijacked to mean to something completely unrelated and totally different.
This broke a bunch of other libraries and resulting
in problems that plague us to this day. and of course the same goes
for BOOST_THROW_EXCEPTION.

Would anyone object if I changed these back to the original (sensible)
meanings?

Robert Ramey

Emil Dotchevski

unread,
Jun 19, 2012, 2:03:35 AM6/19/12
to bo...@lists.boost.org
On Mon, Jun 18, 2012 at 9:55 PM, Robert Ramey <ra...@rrsd.com> wrote:

> At some point, the definition of BOOST_NO_EXCEPTION was
> hijacked to mean to something completely unrelated and totally different.
> This broke a bunch of other libraries and resulting
> in problems that plague us to this day. and of course the same goes
> for BOOST_THROW_EXCEPTION.
>

BOOST_THROW_EXCEPTION (the macro) has never been changed, it did not exist
prior to the acceptance of Boost Exception.

Would anyone object if I changed these back to the original (sensible)
> meanings?
>

You probably mean boost::throw_exception. Yes, I object that being changed
because that would handicap Boost Exception. Note that users of Boost
Exception need other Boost libraries to throw exceptions using
boost::throw_exception in order to take advantage of Boost Exception.

You state that boost::throw_exception isn't sensible. Care to elaborate?
Normally I don't knowingly write non-sensible code. :)

John Maddock

unread,
Jun 19, 2012, 4:47:04 AM6/19/12
to bo...@lists.boost.org
> I am working on a C++ based project which forbids the usage of C++
> exceptions
> but it is still preferable to use Boost libraries at least the ones which
> do
> not make use of C++ exceptions at all. I am especially interested in using
> Boost.Units and Boost.Math.
>
> Which of Boost libraries do NOT make use of C++ exceptions (i did not find
> such a list but maybe its already available somewhere)?

I can't comment on other libraries, but you can turn off use of exceptions
to report errors in Boost.Math via the policies mechanism:
http://www.boost.org/doc/libs/1_49_0/libs/math/doc/sf_and_dist/html/math_toolkit/policy.html

In addition if you're only interested in the TR1 special functions, then the
C compatible libraries provided by Boost.Math (see boost/math/tr1.hpp and
http://www.boost.org/doc/libs/1_49_0/libs/math/doc/sf_and_dist/html/math_toolkit/main_overview/tr1.html)
will set ::errno rather than throw an exception.

HTH, John.

Robert Ramey

unread,
Jun 19, 2012, 1:11:22 PM6/19/12
to bo...@lists.boost.org
Emil Dotchevski wrote:
> On Mon, Jun 18, 2012 at 9:55 PM, Robert Ramey <ra...@rrsd.com> wrote:
>
>> At some point, the definition of BOOST_NO_EXCEPTION was
>> hijacked to mean to something completely unrelated and totally
>> different. This broke a bunch of other libraries and resulting
>> in problems that plague us to this day. and of course the same goes
>> for BOOST_THROW_EXCEPTION.
>>
>
> BOOST_THROW_EXCEPTION (the macro) has never been changed, it did not
> exist prior to the acceptance of Boost Exception.
>
> Would anyone object if I changed these back to the original (sensible)
>> meanings?
>>
>
> You probably mean boost::throw_exception. Yes, I object that being
> changed because that would handicap Boost Exception. Note that users
> of Boost Exception need other Boost libraries to throw exceptions
> using boost::throw_exception in order to take advantage of Boost
> Exception.

Maybe we can reach some sort of compromise on this.

According to
http://www.boost.org/doc/libs/1_49_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__03_defects

"The compiler does not support exception handling (this setting is typically
required by many C++ compilers for embedded platforms). Note that there is
no requirement for boost libraries to honor this configuration setting -
indeed doing so may be impossible in some cases. Those libraries that do
honor this will typically abort if a critical error occurs - you have been
warned!"

a) This definition is in the current and all past documentation and should
be respected by all code
which uses the macro BOOST_NO_EXCEPTIONS

Reason: This is a clear meaning and it's been documented as such for many
years. Your interpretation
is at odds with the documentation. People who read the documentation and
code according to
it will be mislead.

b) boost::throw_exception should be rolled back to it's orginal meaning.

Reason:The problem here is that using something from the main boost
namespace creates
and unexpected and hidden dependency on another library. This occcurs
without the library
user getting notified at all. Much care has been expended so that those
things directly inside
the boost namespace (excluding convenience headers) be things which DO NOT
create
dependencies on other libraries. The current definition of
boost::throw_exception is the only
exception to this.

c) Those who want or need the features of the Boost Exception library should
be able to
get them with:

#include <boost/exception/throw_exception.hpp> // or maybe
<boost/exception.hpp>
...
boost::exception::throw_exception ....

Reason: This is in line with standard practice with all other libraries -
and for good reason.
It exemplifies the "don't pay for what you don't use" which is essential to
the success
of boost.

Robert Ramey

Christopher Kormanyos

unread,
Jun 19, 2012, 3:11:24 PM6/19/12
to bo...@lists.boost.org


> I am working on a C++ based project which forbids the usage of C++ exceptions
> but it is still preferable to use Boost libraries at least the ones which do
> not make use of C++ exceptions at all. I am especially interested in using
> Boost.Units and Boost.Math.
>
> Which of Boost libraries do NOT make use of C++ exceptions (i did not find
> such a list but maybe its already available somewhere)?

If you are using GCC in the project, you can also set some of the
relevant compiler options to *purposely* eliminate proper
exception handling:

-fno-exceptions -fno-enforce-eh-specs

This may result in smaller code and improved performance at the
expense of losing run time exception handling. Although this slightly
breaks standards adherence, these options are useful for projects
with dire performance and size constraints.

Best regards, Chris.

Daniel James

unread,
Jun 19, 2012, 3:20:01 PM6/19/12
to bo...@lists.boost.org
On 19 June 2012 18:11, Robert Ramey <ra...@rrsd.com> wrote:
>
> According to
> http://www.boost.org/doc/libs/1_49_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__03_defects
>
> "The compiler does not support exception handling (this setting is typically
> required by many C++ compilers for embedded platforms). Note that there is
> no requirement for boost libraries to honor this configuration setting -
> indeed doing so may be impossible in some cases. Those libraries that do
> honor this will typically abort if a critical error occurs - you have been
> warned!"
>
> a) This definition is in the current and all past documentation and should
> be respected by all code
> which uses the macro BOOST_NO_EXCEPTIONS

>From http://www.boost.org/doc/libs/1_31_0/libs/utility/throw_exception.html

"It is intended to be used in Boost libraries that need to throw
exceptions, but support configurations and platforms where exceptions
aren't available, as indicated by the presence of the
BOOST_NO_EXCEPTIONS configuration macro."

Suggests that the config documentation isn't in line with how it's
been used for the past nine years.

> b) boost::throw_exception should be rolled back to it's orginal meaning.
>
> Reason:The problem here is that using something from the main boost
> namespace creates
> and unexpected and hidden dependency on another library.  This occcurs
> without the library
> user getting notified at all.  Much care has been expended so that those
> things directly inside
> the boost namespace (excluding convenience headers) be things which DO NOT
> create
> dependencies on other libraries.  The current definition of
> boost::throw_exception is the only
> exception to this.

That's an odd claim to make. Look at: boost::any, boost::array,
boost::bimap etc.

Emil Dotchevski

unread,
Jun 19, 2012, 4:10:38 PM6/19/12
to bo...@lists.boost.org
On Tue, Jun 19, 2012 at 10:11 AM, Robert Ramey <ra...@rrsd.com> wrote:

> b) boost::throw_exception should be rolled back to it's orginal meaning.
>
> Reason:The problem here is that using something from the main boost
> namespace creates
> and unexpected and hidden dependency on another library. This occcurs
> without the library
> user getting notified at all. Much care has been expended so that those
> things directly inside
> the boost namespace (excluding convenience headers) be things which DO NOT
> create
> dependencies on other libraries. The current definition of
> boost::throw_exception is the only
> exception to this.
>

It isn't an exception, there are many other libraries that use the main
boost namespace.

FYI boost::throw_exception is a documented part of Boost Exception:
www.boost.org/doc/libs/release/libs/exception/doc/throw_exception.html.

In terms of dependencies, boost/throw_exception.hpp is extremely light,
orders of magnitude lighter than boost/config.hpp, which is the low water
mark for Boost dependencies.

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Robert Ramey

unread,
Jun 19, 2012, 6:21:45 PM6/19/12
to bo...@lists.boost.org

Robert Ramey

unread,
Jun 19, 2012, 6:51:21 PM6/19/12
to bo...@lists.boost.org
OK - maybe I should phrase this more carefully.

I don't think that something I include from /boost - (other than a
convenience header)
should depend on something more specific like boost/exception,
boost/serialization
or whatever. (Nor do I think that anything not in boost/ should be bart of
the namespace
boost: but rather in in boost::library_name:: );

Of course a number of older libraries like any, array, etc violate this
idea.
I presume that when boost was small it didn't matter and no one likely
expected that boost would become as large as it has. And some more
recent libraries e.g. boost.range also violate this by putting stuff
directly
in the boost namespace. The fact that this occurs doesn't convince me
that it's a good idea.

Basically I want to be including what I expect to include and not include
what I'm not expecting to include. I would like to know that if I use

#include <boost/foreach.hpp>

I'm not including anything outside of the the boost directory and namespace.

Another way of saying this is that the stuff directly in boost/ is sort of
"core boost" and including this stuff doesn't include anything outside of
this "core".
Thus, when I write my code - then I know what I'm getting.

Of course if I include <boost/archive/binary_oarchive.hpp> I can expect to
include a bunch of other stuff and double check accordingly.

And this one of my main complaints about the implementation of
boost.exception.

I include something <boost/throw_exception> and I get a whole layer
of stuff I didn't ask for. It makes my job and everyone else harder than
it has to be.

And of course I'm still smarting from having the BOOST_NO_EXCEPTIONS
definition change while I wasn't looking to from what has always been
documented in a way that makes some sense to something that
I still dont' get.

So I stand behind my suggestions.

Jeffrey Lee Hellrung, Jr.

unread,
Jun 19, 2012, 7:01:24 PM6/19/12
to bo...@lists.boost.org
On Tue, Jun 19, 2012 at 3:51 PM, Robert Ramey <ra...@rrsd.com> wrote:
[...]

> And of course I'm still smarting from having the BOOST_NO_EXCEPTIONS
> definition change while I wasn't looking to from what has always been
> documented in a way that makes some sense to something that
> I still dont' get.
>
> So I stand behind my suggestions.
>

Sorry, I've only been glossing over this discussion. Can someone please
clarify how BOOST_NO_EXCEPTIONS has changed, what specific change Robert
(and possibly others) find troubling, and what practical consequences this
has had or presently has? Ditto for boost::throw_exception.

(For the record, I've glanced at the blurbs on BOOST_NO_EXCEPTIONS within
Boost.Config and Boost.Exception and it's difficult for me to parse what
effect their differences have in practice, and it sounds like others have a
good idea what the problem seems to be.)

- Jeff

Emil Dotchevski

unread,
Jun 19, 2012, 7:34:51 PM6/19/12
to bo...@lists.boost.org
On Tue, Jun 19, 2012 at 4:01 PM, Jeffrey Lee Hellrung, Jr. <
jeffrey....@gmail.com> wrote:

> On Tue, Jun 19, 2012 at 3:51 PM, Robert Ramey <ra...@rrsd.com> wrote:
> [...]
>
> > And of course I'm still smarting from having the BOOST_NO_EXCEPTIONS
> > definition change while I wasn't looking to from what has always been
> > documented in a way that makes some sense to something that
> > I still dont' get.
> >
> > So I stand behind my suggestions.
> >
>
> Sorry, I've only been glossing over this discussion. Can someone please
> clarify how BOOST_NO_EXCEPTIONS has changed, what specific change Robert
> (and possibly others) find troubling, and what practical consequences this
> has had or presently has? Ditto for boost::throw_exception.
>

The semantics of BOOST_NO_EXCEPTIONS have not changed.

boost::throw_exception was altered with the acceptance of Boost Exception,
to automatically make Boost exceptions derive from boost::exception. This
is an empty shell that enables the Boost Exception functionality. Robert
has no use for that functionality and sees the empty shell as overhead.

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Robert Ramey

unread,
Jun 19, 2012, 9:33:41 PM6/19/12
to bo...@lists.boost.org
Jeffrey Lee Hellrung, Jr. wrote:
> On Tue, Jun 19, 2012 at 3:51 PM, Robert Ramey <ra...@rrsd.com> wrote:
> [...]
>
>> And of course I'm still smarting from having the BOOST_NO_EXCEPTIONS
>> definition change while I wasn't looking to from what has always been
>> documented in a way that makes some sense to something that
>> I still dont' get.
>>
>> So I stand behind my suggestions.
>>
>
> Sorry, I've only been glossing over this discussion. Can someone
> please clarify how BOOST_NO_EXCEPTIONS has changed,

Just look higher in the the thread for Emil's definition of
BOOST_NO_EXCEPTIONS.
This is different than the one in the documentation which has never changed
and in fact is part of another library. This situation has lead to much
confusion as to what this macro means as noted higher in the thread.

>what specific
> change Robert (and possibly others) find troubling, and what
> practical consequences this has had or presently has?

Well, it's left me confused about what it's supposed to be.

> Ditto for boost::throw_exception.

Ahhh - a somewhat different case. boost throw exception as implemented
in a very simple way for a very simple purpose. That purpose was to provide
and escape to a global function which one could implement for those
platoforms
which failed to implement exceptions. This is not so uncommon for embedded
systems and some shops which prohibit usage of exceptions.

The function of this was changed with the inclusion of boost.exception which
altered the purpose and implementation of boost::exception in include the
functionality of boost.exeption. You should be able to guess what happened.
All the librarires which has presumed the original operation started to have
changed behavior. Longer build time, dependence on a new library, new
requirement that the library be only used with rtti turned on. For some
unfathonable reason, the change in boost::throw_exception was allowed to
stand. So these libraries including serialization, boost.filesystem, and
some
others had to creat their own macros to implement the behavior of the
original boost::throw_exception. So now we have the case where

a) the original functionality is not found in boost, anyone who needs
it has to implement it on their own.
b) the same functionality is re-implemented in several other libraries
which required a new round of updating of code a documentation,
c) and now we have the situation where a user who invokes something
in the core boost - boost::throw_exception is likely to get a lot more than
he bargained for.

Basically, if one want's the functionality of boost exeception, he should

#include <boost/exception/thow_exception.hpp>
..
boost::exception::throw_exception

and if he want's the original behavior he should be able to say

#include <boost/throw_exception.hpp>
...
boost::throw_exception.

gratuitiously changing the behavior of a long standing function in the
boost core which other library depend on is an unfriendly practice.
I know Emil is convinced that he's done us a big favor by forcing
us to convert to behavior which he knows is better for us, But it's
not his call to make. It's not for me to go around chaning the
behavior of other peoples libraries just because I know better.

> (For the record, I've glanced at the blurbs on BOOST_NO_EXCEPTIONS
> within Boost.Config and Boost.Exception and it's difficult for me to
> parse what effect their differences have in practice, and it sounds
> like others have a good idea what the problem seems to be.)

I hope I clarified this.

Robert Ramey

Emil Dotchevski

unread,
Jun 19, 2012, 10:14:31 PM6/19/12
to bo...@lists.boost.org
On Tue, Jun 19, 2012 at 6:33 PM, Robert Ramey <ra...@rrsd.com> wrote:

> Just look higher in the the thread for Emil's definition of
> BOOST_NO_EXCEPTIONS.
> This is different than the one in the documentation which has never changed
> and in fact is part of another library. This situation has lead to much
> confusion as to what this macro means as noted higher in the thread.
>

Maybe you're confused because you're looking for a change that doesn't
exist? :)

The semantics of the BOOST_NO_EXCEPTIONS configuration macro have not been
changed. If it is defined, Boost Libraries must not throw exceptions. One
way to do this was, and still is, to use boost::throw_exception to throw.

You should be able to guess what happened.
> All the librarires which has presumed the original operation started to
> have
> changed behavior. Longer build time, dependence on a new library, new
> requirement that the library be only used with rtti turned on.


I'm sorry but you'll have to back the "longer build time" claim with hard
data.

You're factually wrong about RTTI, it doesn't have to be turned on.

others had to creat their own macros to implement the behavior of the
> original boost::throw_exception. So now we have the case where
>

That's also wrong, nobody had to do anything. Not only it didn't break any
library, it caught bugs in libraries that called boost::throw_exception
with types that don't derive from std::exception (in violation of its
requirements.)


> a) the original functionality is not found in boost, anyone who needs
> it has to implement it on their own.
>

I'd like to see an example of a program that works with what you call "the
original functionality" but doesn't work with the official
boost::throw_exception.

Basically, if one want's the functionality of boost exeception, he should
>
> #include <boost/exception/thow_exception.hpp>
> ..
> boost::exception::throw_exception
>
> and if he want's the original behavior he should be able to say
>
> #include <boost/throw_exception.hpp>
> ...
> boost::throw_exception.
>

This would work only for exceptions emitted by user code. Boost Exception
is quite useful (to the user) for exceptions that originate in library code.

gratuitiously changing the behavior of a long standing function in the
> boost core which other library depend on is an unfriendly practice.
> I know Emil is convinced that he's done us a big favor by forcing
> us to convert to behavior which he knows is better for us, But it's
> not his call to make.


No it wasn't my call obviously. Boost Exception was admitted by the usual
review process.


> > (For the record, I've glanced at the blurbs on BOOST_NO_EXCEPTIONS
> > within Boost.Config and Boost.Exception and it's difficult for me to
> > parse what effect their differences have in practice, and it sounds
> > like others have a good idea what the problem seems to be.)
>

You'd be able to make a better argument for your case if you understand how
boost::throw_exception was changed (it's been what, 4 years ago now?)

That change boils down to inserting class boost::exception, which does not
implement any functionality, as a base.

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Vicente Botet

unread,
Jun 20, 2012, 3:06:36 AM6/20/12
to bo...@lists.boost.org

Emil Dotchevski-3 wrote
>
> On Tue, Jun 19, 2012 at 6:33 PM, Robert Ramey &lt;ramey@&gt; wrote:
>
>> Just look higher in the the thread for Emil's definition of
>> BOOST_NO_EXCEPTIONS.
>> This is different than the one in the documentation which has never
>> changed
>> and in fact is part of another library. This situation has lead to much
>> confusion as to what this macro means as noted higher in the thread.
>>
>
> Maybe you're confused because you're looking for a change that doesn't
> exist? :)
>
> The semantics of the BOOST_NO_EXCEPTIONS configuration macro have not been
> changed. If it is defined, Boost Libraries must not throw exceptions.
>

I don't interpret it this way. IMO, if BOOST_NO_EXCEPTIONS is defined, Boost
libraries throwing exceptions or using try-catch will just not be supported,
which is quite different.
What I mean, is that this is not a library bug but a feature.

Could you point where it is written that Boost Libraries must not throw
exceptions when BOOST_NO_EXCEPTIONS is defined?

Best,
Vicente




--
View this message in context: http://boost.2283326.n4.nabble.com/Boost-and-exceptions-tp4631441p4631550.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

John Maddock

unread,
Jun 20, 2012, 4:39:46 AM6/20/12
to bo...@lists.boost.org
> Another way of saying this is that the stuff directly in boost/ is sort of
> "core boost" and including this stuff doesn't include anything outside of
> this "core".
> Thus, when I write my code - then I know what I'm getting.

Well maybe the extended throw info that Boost.Exception provides *is* core
boost?

> I include something <boost/throw_exception> and I get a whole layer
> of stuff I didn't ask for. It makes my job and everyone else harder than
> it has to be.

Sure, but it's a pretty small lightweight layer of stuff. I'd be very
surprised if it's presence/absence could be detected in build times.

> And of course I'm still smarting from having the BOOST_NO_EXCEPTIONS
> definition change while I wasn't looking to from what has always been
> documented in a way that makes some sense to something that
> I still dont' get.

It hasn't changed - BOOST_NO_EXCEPTIONS means "no exception handling support
is available in the compiler - so don't use exceptions anywhere". When
defined the Boost.Exception code doesn't even get #included.

And while I realize that *you* may not have been looking when this change
happened, remember that Boost.Exception (including this change) was
reviewed, and as I recall got a lot of discussion.

BTW there is a macro - BOOST_EXCEPTION_DISABLE - which disables use of
Boost.Exception and reverts back to original boost/throw_exception.hpp
behavior. Of course that's a global change which can't be used on a
library-by-library basis. But frankly, I would prefer it if all libraries
were on the same page here and all used BOOST_THROW_EXCETION consistently.

Just my 2c... John.

Robert Ramey

unread,
Jun 20, 2012, 1:13:51 PM6/20/12
to bo...@lists.boost.org
John Maddock wrote:
> Well maybe the extended throw info that Boost.Exception provides *is*
> core boost?

lol - Surprize!, it apparently it already is. Problem is, I don't like
surprises.

> And while I realize that *you* may not have been looking when this
> change happened, remember that Boost.Exception (including this
> change) was reviewed, and as I recall got a lot of discussion.

Hmmm - so this was "extensively" reviewed but no one thought
to inform users of the then current system. I only discovered it
when I started to have some sort of problems with the serialization
library. (I forget the details). So by definition it wasn't an unobstrusive
change.

The whole way this was done conflicts with the whole Boost
cooperative development model in a fundamental way. The whole
concept of development using other libraries has to be based
on the premise that once established, a library functionality can't be
changed. If one can't depend on that, then it would require me
going back and reviewing all the changes in libraries that I use
every time there's a change to verify that my origiginal understanding
of what the library does is still the same.

The new functionality should have been given a new name. There is/was no
reason that authors of other code couldn't be sent a email promoting
the benefits of the new alternative and trying to convince them that
it's worth switchiing. This is the appropriate way to do this.

> But frankly, I would prefer it if all
> libraries were on the same page here and all used
> BOOST_THROW_EXCETION consistently.

lol - you mean like the way it used to be? that's my point.

Robert Ramey

Peter Dimov

unread,
Jun 20, 2012, 1:26:27 PM6/20/12
to bo...@lists.boost.org
Robert Ramey wrote:
> Hmmm - so this was "extensively" reviewed but no one thought
> to inform users of the then current system. I only discovered it
> when I started to have some sort of problems with the serialization
> library. (I forget the details). So by definition it wasn't an
> unobstrusive
> change.

There were some growing pains, but everything got identified and fixed, did
it not?

And, realistically, there is no other way to iron out the details... at some
point things have to be deployed and the objections addressed.

Nevin Liber

unread,
Jun 20, 2012, 1:49:35 PM6/20/12
to bo...@lists.boost.org
On 20 June 2012 12:13, Robert Ramey <ra...@rrsd.com> wrote:

> The whole way this was done conflicts with the whole Boost
> cooperative development model in a fundamental way. The whole
> concept of development using other libraries has to be based
> on the premise that once established, a library functionality can't be
> changed.


While the bar on changing functionality and/or interfaces is high, it isn't
(and never has been, as far as I know) absolute (and it isn't even as high
as the C++ standard, nor should it be). As it says in the Boost FAQ <
http://www.boost.org/users/faq.html>: "Many of the Boost libraries are
actively maintained and improved, so backward compatibility with prior
version isn't always possible."
--
Nevin ":-)" Liber <mailto:ne...@eviloverlord.com> (847) 691-1404

Jeffrey Lee Hellrung, Jr.

unread,
Jun 20, 2012, 3:23:09 PM6/20/12
to bo...@lists.boost.org
On Tue, Jun 19, 2012 at 6:33 PM, Robert Ramey <ra...@rrsd.com> wrote:

> Jeffrey Lee Hellrung, Jr. wrote:
> > On Tue, Jun 19, 2012 at 3:51 PM, Robert Ramey <ra...@rrsd.com> wrote:
> > [...]
> >
> >> And of course I'm still smarting from having the BOOST_NO_EXCEPTIONS
> >> definition change while I wasn't looking to from what has always been
> >> documented in a way that makes some sense to something that
> >> I still dont' get.
> >>
> >> So I stand behind my suggestions.
> >>
> >
> > Sorry, I've only been glossing over this discussion. Can someone
> > please clarify how BOOST_NO_EXCEPTIONS has changed,
>
> Just look higher in the the thread for Emil's definition of
> BOOST_NO_EXCEPTIONS.
> This is different than the one in the documentation which has never changed
> and in fact is part of another library. This situation has lead to much
> confusion as to what this macro means as noted higher in the thread.
>
> >what specific
> > change Robert (and possibly others) find troubling, and what
> > practical consequences this has had or presently has?
>
> Well, it's left me confused about what it's supposed to be.
>

Okay, Boost.Config says about BOOST_NO_EXCEPTIONS that

"The compiler does not support exception handling...Note that there is no
requirement for boost libraries to honor this configuration setting"

while Boost.Exception says

"This macro disables exception handling in Boost, forwarding all exceptions
to a user-defined non-template version of
boost::throw_exception<http://www.boost.org/doc/libs/1_49_0/libs/exception/doc/throw_exception.html>
."

Is the confusion primarily that there are two descriptions of
BOOST_NO_EXCEPTIONS? I certainly find this confusing, and it would be great
if these descriptions can be brought more in line with one another.

Is the confusion whether this applies to a property of the compiler (as
Boost.Config suggests), or whether it is a user-defined setting (as one may
infer from Boost.Exception's description)? From a library's point-of-view,
I don't see any practical difference; if a library wants to support a
defined BOOST_NO_EXCEPTIONS in either case, it can't have any exception
handling code.

Is the confusion whether respecting the disabling of exception handling is
optional within a given library (as stated by Boost.Config) or mandatory,
with any exceptions going to boost::throw_exception (as one may infer from
Boost.Exception's description)? Except for the apparent requirement implied
by Boost.Exception that all libraries will "throw" exceptions through
boost::throw_exception when BOOST_NO_EXCEPTIONS is defined, these don't
seem incompatible. If a library uses boost::throw_exception to "throw"
exceptions, it likely will do so consistently, so will automatically
support disabling exception handling. On the other hand, if it doesn't,
well, it either doesn't support the disabling of exception handling or it
uses its own mechanisms to deal with "exceptional" situations. I presume
some libraries may take the latter approach? Meaning the assertion that all
exceptions are forwarded to boost::throw_exception is inaccurate?

> Ditto for boost::throw_exception.
>
> Ahhh - a somewhat different case. boost throw exception as implemented
> in a very simple way for a very simple purpose. That purpose was to
> provide
> and escape to a global function which one could implement for those
> platoforms
> which failed to implement exceptions. This is not so uncommon for embedded
> systems and some shops which prohibit usage of exceptions.
>

Okay, I'm following.


> The function of this was changed with the inclusion of boost.exception
> which
> altered the purpose and implementation of boost::exception in include the
> functionality of boost.exeption. You should be able to guess what
> happened.
> All the librarires which has presumed the original operation started to
> have
> changed behavior.


Okay, so I infer that, "before", "boost::throw_exception(e);" was
equivalent to "throw e;"; "now", it is equivalent to "throw
enable_current_exception(enable_error_info(e));". enable_error_info ensures
the thrown object derives from boost::exception, while
enable_current_exception "enables exception_ptr support". Okay, I admit,
it's been a while since I've read the Boost.Exception docs and I forgot
what that "exception_ptr support" means, but I think the point is that the
actual thrown object is different "now" from "before". Although I think the
idea was that the new thrown object still inherited publicly from the
original object, so catch blocks should still function as before.

Longer build time, dependence on a new library, new
> requirement that the library be only used with rtti turned on.


At this point, based on Emil's and John's responses, it seems these first 2
issues aren't really problems in practice, while the 3rd issue is simply
not the case.

For some
> unfathonable reason, the change in boost::throw_exception was allowed to
> stand. So these libraries including serialization, boost.filesystem, and
> some
> others had to creat their own macros to implement the behavior of the
> original boost::throw_exception.


Was actual code broken due to the change, and, if so, do you remember any
examples? Or were those libraries authors who reimplemented the original
functionality simply concerned with the overhead introduced by
boost::throw_exception?

So now we have the case where
>
> a) the original functionality is not found in boost, anyone who needs
> it has to implement it on their own.
> b) the same functionality is re-implemented in several other libraries
> which required a new round of updating of code a documentation,
> c) and now we have the situation where a user who invokes something
> in the core boost - boost::throw_exception is likely to get a lot more than
> he bargained for.


> Basically, if one want's the functionality of boost exeception, he should
>
> #include <boost/exception/thow_exception.hpp>
> ..
> boost::exception::throw_exception
>
> and if he want's the original behavior he should be able to say
>
> #include <boost/throw_exception.hpp>
> ...
> boost::throw_exception.
>
> gratuitiously changing the behavior of a long standing function in the
> boost core which other library depend on is an unfriendly practice.
> I know Emil is convinced that he's done us a big favor by forcing
> us to convert to behavior which he knows is better for us, But it's
> not his call to make. It's not for me to go around chaning the
> behavior of other peoples libraries just because I know better.
>

Okay, fair enough; this is an understandable but more philosophical point
concerning development practices. At this point, though,
boost::throw_exception has had these semantics since...well whenever
Boost.Exception was released, which appears to be 1.36 based on my changing
the version number in the URL of the documentation of
boost::throw_exception :/ And it seems like changing it *back* to the
pre-1.36 functionality would break more code than the change introduced in
1.36.

> (For the record, I've glanced at the blurbs on BOOST_NO_EXCEPTIONS
> > within Boost.Config and Boost.Exception and it's difficult for me to
> > parse what effect their differences have in practice, and it sounds
> > like others have a good idea what the problem seems to be.)
>
> I hope I clarified this.
>

Clearly not entirely :)

Jeffrey Lee Hellrung, Jr.

unread,
Jun 20, 2012, 3:33:46 PM6/20/12
to bo...@lists.boost.org
On Tue, Jun 19, 2012 at 7:14 PM, Emil Dotchevski
<emildot...@gmail.com>wrote:

> On Tue, Jun 19, 2012 at 6:33 PM, Robert Ramey <ra...@rrsd.com> wrote:
>
> > Just look higher in the the thread for Emil's definition of
> > BOOST_NO_EXCEPTIONS.
> > This is different than the one in the documentation which has never
> changed
> > and in fact is part of another library. This situation has lead to much
> > confusion as to what this macro means as noted higher in the thread.
> >
>
> Maybe you're confused because you're looking for a change that doesn't
> exist? :)
>
> The semantics of the BOOST_NO_EXCEPTIONS configuration macro have not been
> changed. If it is defined, Boost Libraries must not throw exceptions.


This seems to be contradict [1], which specifically says "there is no
requirement for boost libraries to honor this configuration setting". Which
seems to imply that a library may simply choose to not be supported (i.e.,
us try/catch/throw) if BOOST_NO_EXCEPTIONS is defined.

One
> way to do this was, and still is, to use boost::throw_exception to throw.
>

Again, [2] seems to indicate that *all* exceptions in *all* of Boost will
be forwarded to boost::throw_exception if BOOST_NO_EXCEPTIONS is defined,
but your statement above seems to allow a given library's exceptions to be
dealt with as the library sees fit, possibly using boost::throw_exception
but possibly not.

All in all, the combination of [1] and [2] does not give me a clear picture
about the semantics of BOOST_NO_EXCEPTIONS, but perhaps it doesn't make any
practical difference? I still find this documentation combination
confusing, though :(

- Jeff

[1]
http://www.boost.org/doc/libs/1_49_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__03_defects
[2]
http://www.boost.org/doc/libs/1_49_0/libs/exception/doc/configuration_macros.html

Emil Dotchevski

unread,
Jun 20, 2012, 4:00:24 PM6/20/12
to bo...@lists.boost.org
On Wed, Jun 20, 2012 at 10:13 AM, Robert Ramey <ra...@rrsd.com> wrote:

> Hmmm - so this was "extensively" reviewed but no one thought
> to inform users of the then current system. I only discovered it
> when I started to have some sort of problems with the serialization
> library. (I forget the details). So by definition it wasn't an
> unobstrusive
> change.
>

No, the change wasn't entirely unobtrusive, a few wrinkles had to be ironed
out.

If you insist, I don't mind discussing the initial deployment of Boost
Exception, but perhaps it'd be a better use of everyone's time to stick to
the present.

The whole way this was done conflicts with the whole Boost
> cooperative development model in a fundamental way. The whole
> concept of development using other libraries has to be based
> on the premise that once established, a library functionality can't be
> changed.


Obviously libraries change. The important thing is to keep changes
compatible with existing code.

The "new" (several years old now) boost::throw_exception functionality is
100% compatible with the original.

> But frankly, I would prefer it if all
> > libraries were on the same page here and all used
> > BOOST_THROW_EXCETION consistently.
>
> lol - you mean like the way it used to be? that's my point.
>

FYI, there was no BOOST_THROW_EXCEPTION before Boost Exception.

What he means is that BOOST_THROW_EXCEPTION is preferable to
boost::throw_exception, because it allows more complete messages by
boost::diagnostic_information.

--
Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Robert Ramey

unread,
Jun 20, 2012, 5:55:00 PM6/20/12
to bo...@lists.boost.org
Jeffrey Lee Hellrung, Jr. wrote:

> Longer build time, dependence on a new library, new
>> requirement that the library be only used with rtti turned on.
>
>
> At this point, based on Emil's and John's responses, it seems these
> first 2 issues aren't really problems in practice, while the 3rd
> issue is simply
> not the case.

It may or may not be the case now. This isn't really relevant to my
complaint
as you'll see below

> For some
>> unfathonable reason, the change in boost::throw_exception was
>> allowed to stand. So these libraries including serialization,
>> boost.filesystem, and some
>> others had to creat their own macros to implement the behavior of the
>> original boost::throw_exception.
>

> Was actual code broken due to the change,

Well it was noticed because it created problems.

> and, if so, do you remember any examples?

of course not. I suppose you could troll the list if you were
really interested.

> Or were those libraries authors who reimplemented the
> original functionality simply concerned with the overhead introduced
> by boost::throw_exception?

Here's the real situation. One invests a HUGE amount of effort
that it takes to get a libary over the various boost hurdles. I don't think
very many people have any idea what it takes to get something
like file_system, serialization, or others into boost. After this
huge initial effort you've got to spend some time cleaning up some
detail and handling user complaints, upgrading documentation etc.
(don't even mention the time it takes to deal with boost tools).
So now you can sort of relax as things settle down, you've responded
to all the questions by upgrading your documentation, etc. etc.
Of course by the time this happens, you're way behind on your
"real" work and trying to catch up with that.

Then you get a problem. OK well you made the library, you better
fix it. After a fair amount of sleuthing, you track it down to a gratuitous
change to some other library whose behavior has changed without
you noticing. This is incredibly disheartening. You've invested huge
amount of effort to get something of this scale "over the hump" and
now you've been undermined by someone who really isn't being
considerate and/or doesn't know the implications of what he's doing.
And, if accepted, this would mean a whole new level of effort you have
to engage in - just to keep things from breaking.

Originally you dealt with this by building a moat around your app/library
and you only depend on other aps/libraries which you can really trust
to not let you down. So you do the only thing you really can do. You
tweak you app so it doesn't depend on the offending component any
more. You have to do this be it just takes too much time to really
investigate the implications of introducing a dependency on a new
library just to relplace a simple macro. So now your off the hook
and you can move on with your life - but boost itself is worse off
because of it since now the code base is more confusing and
includes replicated functionality which it didn't have before.

And it's even worse - Basically it's like an army where everyone wears
the same uniform. Now someone with the same uniform as you stabs
you in the back, and now you can't trust anyone anymore. So
all the assumptions that you used to be able to make - (e.g.
I'm not going to be surprised by something out of left field)
aren't true any more. So it slows everyone down in the future.

And it's even bigger than this. Have you noticed that in many shops
the ONLY external library they permit is boost? Have you noticed
that the first place people look for C++ code is boost - even though
there are at least 100's (maybe 1000's) of C++ code modules
available at the touch of a buttone. It's two things

a) The review process - which catches most of the situations like this.
b) Requirement for a test suite and regular execution thereof.

these two things diminish problems like the example here. To me
this situation is break down in the revew process - which thankfully
is rare. If situations like this were to occur on a regular basis
boost wouldn't be nearly as successful as it has been.

I hope it should be obvious that I don't see posts like:
"you're wrong - it doesn't take that long to compile (anymore)" or
"it doesn't have this problem (anymore)" are not really relevant to
my concerns. They just miss the real point.

Honestly, I have no opinion at all on the merits of boost exception.
Even more honest, I haven't even looked at the documentation or
code. This is not about boost exception - its about how a developer
can be expected to cope if this practice is permited to continue.

> Okay, fair enough; this is an understandable but more philosophical
> point concerning development practices.

right. For me it is the main point.

> At this point, though,
> boost::throw_exception has had these semantics since...well whenever
> Boost.Exception was released, which appears to be 1.36 based on my
> changing the version number in the URL of the documentation of
> boost::throw_exception :/ And it seems like changing it *back* to the
> pre-1.36 functionality would break more code than the change
> introduced in
> 1.36.

lol I didn't follow that. It doesn't matter though as we've already excluded
it from our libraries and are unlikely to go back and revisit it as we've
got other fish to fry.

>> (For the record, I've glanced at the blurbs on BOOST_NO_EXCEPTIONS
>>> within Boost.Config and Boost.Exception and it's difficult for me to
>>> parse what effect their differences have in practice, and it sounds
>>> like others have a good idea what the problem seems to be.)
>>
>> I hope I clarified this.
>>
>
> Clearly not entirely :)

lol - +1 I"m as confused as ever on the subject. From my standpoint,
I'm just that much more greatful that I severed the dependence on this
library.

FWIW, I think boost.exception would have had much better reception from
other authors if the author had

a) implemented as I proposed.
b) let it "rippen" over a couple of releases.
c) made a pitch/case to other library authors about what the benefits would
be if his library were included instead of the traditional way of doing
things
d) explained how users would appreciate the "upgrade".
e) explained how there wouldn't be any downsides.
f) explained how the library author wouldn't really have to do anything but
a couple of simple edits.
g) and accepted the fact that it would take time for people to migrate.
h) and accepted the fact that in spite of his best efforts, he might not be
able to convince everyone.

I know it seems like it's a lot easier to just ram it down everyone's throat
while they're
attention is focused elsewhere. And it likely is - in the short run. But
hopefully this thread might
convince the next person considers this strategy that it's not really the
shortcut it would seem to be.

Robert Ramey

Mathias Gaunard

unread,
Jun 20, 2012, 5:41:26 PM6/20/12
to bo...@lists.boost.org
On 20/06/2012 00:51, Robert Ramey wrote:

> I don't think that something I include from /boost - (other than a
> convenience header)
> should depend on something more specific like boost/exception,
> boost/serialization
> or whatever.

First, preventing interdependence between libraries is useless.

Second, boost::throw_exception is not strictly part of Boost.Exception.
It's a component from the very core of Boost that allows people to
disable exceptions.

Boost.Exception is a set of exception types with rich RTTI that allow
transfers between threads and arbitrary attaching of data.

They're different things, though they can be integrated to work
together, depending on whether BOOST_EXCEPTION_DISABLE is set or not.

Mathias Gaunard

unread,
Jun 20, 2012, 5:43:56 PM6/20/12
to bo...@lists.boost.org
On 20/06/2012 03:33, Robert Ramey wrote:

> a) the original functionality is not found in boost, anyone who needs
> it has to implement it on their own.

It is.
Define BOOST_EXCEPTION_DISABLE for boost::throw_exception not to use
Boost.Exception.

Mathias Gaunard

unread,
Jun 20, 2012, 6:06:10 PM6/20/12
to bo...@lists.boost.org
On 20/06/2012 23:55, Robert Ramey wrote:

> Here's the real situation. One invests a HUGE amount of effort
> that it takes to get a libary over the various boost hurdles. I don't think
> very many people have any idea what it takes to get something
> like file_system, serialization, or others into boost.

A certain level of quality of expected, but calling it huge is an
overstatement. A lot of large software development companies have much
stricter requirements and expectations for software quality before they
ship it.


> After this
> huge initial effort you've got to spend some time cleaning up some
> detail and handling user complaints, upgrading documentation etc.
> (don't even mention the time it takes to deal with boost tools).
> So now you can sort of relax as things settle down, you've responded
> to all the questions by upgrading your documentation, etc. etc.
> Of course by the time this happens, you're way behind on your
> "real" work and trying to catch up with that.

Maintenance is part of software development. Software is never finished
and always requires more work. Software that has ceased to be maintained
may as well be thrown away.

There will *always* be problems as new architectures, new compilers, new
version of dependencies get introduced. No software is bug free.


> Then you get a problem. OK well you made the library, you better
> fix it. After a fair amount of sleuthing, you track it down to a gratuitous
> change to some other library whose behavior has changed without
> you noticing. This is incredibly disheartening. You've invested huge
> amount of effort to get something of this scale "over the hump" and
> now you've been undermined by someone who really isn't being
> considerate and/or doesn't know the implications of what he's doing.
> And, if accepted, this would mean a whole new level of effort you have
> to engage in - just to keep things from breaking.

This is why we have tests. When doing development on anything, with
possibly several other things using it or depending on it, it is
expected that doing changes might break things.

Doing regular tests on a full matrix of compilers and configurations can
be used to clearly identify when a problem was introduced, what it is
and in what situations and configurations it causes problems.

Of course, this needs a good testing mechanism in place to clearly
identify which commit is responsible for a test breaking.
Boost has something a bit like this, but my guess is that you don't
really make use of it in your developments. Efforts are being made by
Dave and others to move to better tools (in this case buildbot) to make
the whole of Boost more productive.


> Originally you dealt with this by building a moat around your app/library
> and you only depend on other aps/libraries which you can really trust
> to not let you down.

You normally only need to take such actions for the stable version of
your library, not for the development branch.

It has been suggested that each library should have its own stable branch.


> And it's even worse - Basically it's like an army where everyone wears
> the same uniform. Now someone with the same uniform as you stabs
> you in the back, and now you can't trust anyone anymore. So
> all the assumptions that you used to be able to make - (e.g.
> I'm not going to be surprised by something out of left field)
> aren't true any more. So it slows everyone down in the future.

Most software development involves working with other people. It can
indeed be annoying when someone breaks your stuff by making a change
elsewhere in the code. It happens every day in the projects I work on.
It's part of the job.


> Honestly, I have no opinion at all on the merits of boost exception.
> Even more honest, I haven't even looked at the documentation or
> code. This is not about boost exception - its about how a developer
> can be expected to cope if this practice is permited to continue.

I've personally found that Boost.Exception has quite a few problems, yet
it has some useful functionality that sometimes I need.

Don't use it when you don't need it, use it when you do. But as far as
throw_exception is concerned, it's pretty much as if it weren't there.


>>> (For the record, I've glanced at the blurbs on BOOST_NO_EXCEPTIONS
>>>> within Boost.Config and Boost.Exception and it's difficult for me to
>>>> parse what effect their differences have in practice, and it sounds
>>>> like others have a good idea what the problem seems to be.)
>>>
>>> I hope I clarified this.
>>>
>>
>> Clearly not entirely :)
>
> lol - +1 I"m as confused as ever on the subject. From my standpoint,
> I'm just that much more greatful that I severed the dependence on this
> library.

BOOST_NO_EXCEPTIONS is defined if it is detected that the compiler has
disabled exceptions.

Users may also manually define BOOST_NO_EXCEPTIONS to disable exceptions
regardless of what is detected (useful for compilers which lack a
mechanism to disable exceptions explicitly or where it cannot be detected).

Nevin Liber

unread,
Jun 20, 2012, 6:07:14 PM6/20/12
to bo...@lists.boost.org
On 20 June 2012 16:55, Robert Ramey <ra...@rrsd.com> wrote:

>
> After a fair amount of sleuthing, you track it down to a gratuitous
> change to some other library whose behavior has changed without
> you noticing. This is incredibly disheartening.
>

Here's the *real* situation: Welcome to software development.

This can (and usually does) happen whenever I change any libraries,
compilers or even compiler flags. It has nothing to do with Boost. Heck,
it's been accelerated because compilers and libraries are in various stages
of C++11 compliance.

Is the burden higher on library writers? Absolutely.

It's the nature of the beast. The spectrum is from putting up with a
little pain every time something about your environment changes to locking
everything down so you have no external dependencies.

The alternative is stagnation. Every change has the potential to break
something.
--
Nevin ":-)" Liber <mailto:ne...@eviloverlord.com> (847) 691-1404

Emil Dotchevski

unread,
Jun 20, 2012, 6:11:17 PM6/20/12
to bo...@lists.boost.org
On Wed, Jun 20, 2012 at 2:55 PM, Robert Ramey <ra...@rrsd.com> wrote:

> Jeffrey Lee Hellrung, Jr. wrote:
>
> > Longer build time, dependence on a new library, new
> >> requirement that the library be only used with rtti turned on.
> >
> >
> > At this point, based on Emil's and John's responses, it seems these
> > first 2 issues aren't really problems in practice, while the 3rd
> > issue is simply
> > not the case.
>
> It may or may not be the case now.
>

It never was the case.

FWIW, I think boost.exception would have had much better reception from
> other authors if the author had


I am quite happy with the reception the library got, during the review
process and after.

>
> b) let it "rippen" over a couple of releases.
> c) made a pitch/case to other library authors about what the benefits would
> be if his library were included instead of the traditional way of doing
> things
> d) explained how users would appreciate the "upgrade".
> e) explained how there wouldn't be any downsides.
> f) explained how the library author wouldn't really have to do anything but
> a couple of simple edits.
> g) and accepted the fact that it would take time for people to migrate.
> h) and accepted the fact that in spite of his best efforts, he might not be
> able to convince everyone.
>
> I know it seems like it's a lot easier to just ram it down everyone's
> throat
> while they're
> attention is focused elsewhere.


The Boost review process doesn't seem to resemble ramming things down
throats. :)

It is clear that you don't approve of the current definition of
boost::throw_exception. That's fine, you don't have to use it, but if you
want to criticize it, it'd help if you first understand it. Otherwise you
end up making unsubstantiated claims, rather than pointing out real
problems.

--
Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Robert Ramey

unread,
Jun 20, 2012, 7:56:14 PM6/20/12
to bo...@lists.boost.org
Emil Dotchevski wrote:
> On Wed, Jun 20, 2012 at 2:55 PM, Robert Ramey <ra...@rrsd.com> wrote:

> It is clear that you don't approve of the current definition of
> boost::throw_exception. That's fine, you don't have to use it, but if
> you want to criticize it, it'd help if you first understand it.
> Otherwise you end up making unsubstantiated claims, rather than
> pointing out real problems.

lol - I haven't critcised boost exception. I only understand it in
the very vaguest terms. I've said this in as many ways as I can
think of. I don't know what else to do.

I have criticised the way it's introduction into boost was handled.
The few posts in the thread which have addressed my critcism
have failed to convince me that I'm off track here.

Robert Ramey.

Robert Ramey

unread,
Jun 20, 2012, 8:19:55 PM6/20/12
to bo...@lists.boost.org
Nevin Liber wrote:
> On 20 June 2012 16:55, Robert Ramey <ra...@rrsd.com> wrote:
>
>>
>> After a fair amount of sleuthing, you track it down to a gratuitous
>> change to some other library whose behavior has changed without
>> you noticing. This is incredibly disheartening.
>>
>
> Here's the *real* situation: Welcome to software development.

True - it's bad enough already - So let's agree not to make it worse
if we can avoid it.

To put it another way. Good practices will never totally eliminate
problems. But they have a HUGE positive effect. It would have
cost almost nothing to avoid this situation.

> It's the nature of the beast. The spectrum is from putting up with a
> little pain every time something about your environment changes to
> locking everything down so you have no external dependencies.

> The alternative is stagnation. Every change has the potential to
> break something.


TL;DR;

I see these and simlar arguments as variants of

"It's not going to be perfect anyway, so don't sweat the small stuff"

(I'm sorry if I mischaracterized your position here - but that's
the way I interpret it)

And I see this is at the bottom of many, many, problems in software
development. It shows up in all sorts of ways that drive me crazy
as a user and software developer. For example.

as a user:
a) constant "upgrades/bug fixes" which load up my computer with tons of junk
and make it slower.
b) quirky applications which have all sorts of unexpected behavior which
makes me feel stupid.
c) stuff that doesn't work together as it should
d) weired indecipherable dependencies - load one component and some
"unrelated" application breaks

as a developer
a) situation as you describe - change one thing - and something else breaks.
b) large amounts of resources just dedicated to keeping things running
c) inability to enhance programs wihtout huge effort

These latter are our fault. And I disagree that the situation is hopeless
and inevitable. They occur because we do things that create these
problems and we should know better. In fact we DO know better.
But often the person who takes the shortcut is not the person who
suffers the concequences, there an irrestible temptation to just do it
and let someone else worry about it.

To me this is the main problem with the popular scripting languages.
You can throw tother something that works in no time and the boss loves
it. But you have all the problems mentioned about. C++ is almost
unique in it's ability to create and enforce strong typing. This what
makes it special. It IS possible to make something (almost) perfect,
something (almost) unbreakable, and something (almost) optimally
efficient. It demans work that other languages don't but it offers
the opportunity to get off the endless treadmill of maintainng
a years old application as a career. In order to come close to
this idea it does require some disciplen - lack of which I'm addressing
here - but it comes close to the holy grail - make it one and never
have to go back to it. Lot's of boost libraries come close to
achieving this - that's why we love boost.

sorry for the rant.

Robert Ramey

Robert Ramey

unread,
Jun 20, 2012, 8:21:37 PM6/20/12
to bo...@lists.boost.org
Nevin Liber wrote:
> On 20 June 2012 16:55, Robert Ramey <ra...@rrsd.com> wrote:

> The alternative is stagnation.

This I disagree with

>Every change has the potential to break something.

This I disagree with also.

Robert Ramey

Emil Dotchevski

unread,
Jun 20, 2012, 9:17:39 PM6/20/12
to bo...@lists.boost.org
On Wed, Jun 20, 2012 at 4:56 PM, Robert Ramey <ra...@rrsd.com> wrote:

> Emil Dotchevski wrote:
> > On Wed, Jun 20, 2012 at 2:55 PM, Robert Ramey <ra...@rrsd.com> wrote:
>
> > It is clear that you don't approve of the current definition of
> > boost::throw_exception. That's fine, you don't have to use it, but if
> > you want to criticize it, it'd help if you first understand it.
> > Otherwise you end up making unsubstantiated claims, rather than
> > pointing out real problems.
>
> lol - I haven't critcised boost exception. I only understand it in
> the very vaguest terms. I've said this in as many ways as I can
> think of. I don't know what else to do.
>

I'm confused. I thought you were complaining about build times and
dependencies.

I mean, if there is a problem with boost::throw_exception or any other part
of Boost Exception, I'd like to know about it.

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

John Maddock

unread,
Jun 21, 2012, 5:14:02 AM6/21/12
to bo...@lists.boost.org
> Here's the real situation. One invests a HUGE amount of effort
> that it takes to get a libary over the various boost hurdles. I don't
> think
> very many people have any idea what it takes to get something
> like file_system, serialization, or others into boost. After this
> huge initial effort you've got to spend some time cleaning up some
> detail and handling user complaints, upgrading documentation etc.
> (don't even mention the time it takes to deal with boost tools).
> So now you can sort of relax as things settle down, you've responded
> to all the questions by upgrading your documentation, etc. etc.
> Of course by the time this happens, you're way behind on your
> "real" work and trying to catch up with that.

For sure, and I've been bitten by that a few times, come to that I think I
may have caused that a few times for which I apologise.

I also was seem to dimly remember being bitten by the changes to
Boost.Exception when they happened, but you no what? Not once since, never.
That's a pretty good record IMO.

> FWIW, I think boost.exception would have had much better reception from
> other authors if the author had
>
> a) implemented as I proposed.
> b) let it "rippen" over a couple of releases.
> c) made a pitch/case to other library authors about what the benefits
> would
> be if his library were included instead of the traditional way of doing
> things
> d) explained how users would appreciate the "upgrade".
> e) explained how there wouldn't be any downsides.
> f) explained how the library author wouldn't really have to do anything
> but a couple of simple edits.
> g) and accepted the fact that it would take time for people to migrate.
> h) and accepted the fact that in spite of his best efforts, he might not
> be able to convince everyone.

All of which are good arguments, except they're *4 years too late*.

Sorry but suggesting we just revert something back to a way it never
actually was in the first place, after it's been functioning apparently OK
for 4 years, and which users may well have been relying on over that time
isn't going to wash.

Surprising how fast time goes yours, John.

Robert Ramey

unread,
Jun 21, 2012, 1:12:55 PM6/21/12
to bo...@lists.boost.org
John Maddock wrote:
> Sorry but suggesting we just revert something back to a way it never
> actually was in the first place, after it's been functioning
> apparently OK for 4 years, and which users may well have been relying
> on over that time isn't going to wash.

lol - I guess the best arguement against my proposal would be to say
that my proposal at this point (if that's what it was) would be engaging in
the same
practice that I've been arguing against in the first place. Which would
be a tough argument to counter. It's sort of like eating my own tail. lol

If this discussion prevents some future library author from gratuitously
extending the dependencies of existing code, it will have been worthwhile.

Still, I would like to consider one thing that might inprove things;

a) boost::throw_exception would be deprecated. (not changed)
b) the same facility would be invoked by:

#include <boost/exception/throw_exception.hpp>
...
boost::exception::throw_exception ....

as usual, the deprecation would mean
a) an initial period of compile time warning
b) eventual elmination.

This later stage would create a compile time error which would be
trivial fixable. No program bugs would be introduced.

This would advise programmers who've been inadvertantly
including boost::exception that they are in fact doing so and
give them the opportunity to decide whether or not they
really want to do this. Of course this might require them to
read at least some of the documentation of boost exception.
This is not a bad thing.

Authors of new code would conciously decide whether
or not they were including boost exception. Also not
a bad thing.

Note that I'm not making any judgment on the merits
of boost exception itself. This about limiting unintentional
dependcies. Boost exception just happens to be the
main example here.

Robert Ramey

Vicente J. Botet Escriba

unread,
Jun 21, 2012, 5:40:32 PM6/21/12
to bo...@lists.boost.org
Le 21/06/12 19:12, Robert Ramey a écrit :
> John Maddock wrote:
>> Sorry but suggesting we just revert something back to a way it never
>> actually was in the first place, after it's been functioning
>> apparently OK for 4 years, and which users may well have been relying
>> on over that time isn't going to wash.
> lol - I guess the best arguement against my proposal would be to say
> that my proposal at this point (if that's what it was) would be engaging in
> the same
> practice that I've been arguing against in the first place. Which would
> be a tough argument to counter. It's sort of like eating my own tail. lol
>
> If this discussion prevents some future library author from gratuitously
> extending the dependencies of existing code, it will have been worthwhile.
>
> Still, I would like to consider one thing that might inprove things;
>
> a) boost::throw_exception would be deprecated. (not changed)
> b) the same facility would be invoked by:
>
> #include<boost/exception/throw_exception.hpp>
> ...
> boost::exception::throw_exception ....
>
>

Hi Robert,

I propose you a different thing. Instead of changing again the name of
boost::throw_exception, we can add something like
boost::throw_strict_exception that will either throw the given exception
or no throw at all depending on BOOST_NO_EXCEPTIONS as it was the case
before the introduction of Boost.Exception.

Best,
Vicente

Emil Dotchevski

unread,
Jun 21, 2012, 6:07:48 PM6/21/12
to bo...@lists.boost.org
On Thu, Jun 21, 2012 at 10:12 AM, Robert Ramey <ra...@rrsd.com> wrote:

> a) boost::throw_exception would be deprecated. (not changed)
>

I'm yet to see a problem identified with boost::throw_exception, in terms
of anything at all -- speed, space, build times, whatever.

Removing functionality from a function breaks code. What is the pain you
want to alleviate, that justifies deprecation?

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Robert Ramey

unread,
Jun 21, 2012, 7:55:35 PM6/21/12
to bo...@lists.boost.org
Vicente J. Botet Escriba wrote:
>
>
> Hi Robert,
>
> I propose you a different thing. Instead of changing again the name of
> boost::throw_exception, we can add something like
> boost::throw_strict_exception that will either throw the given
> exception or no throw at all depending on BOOST_NO_EXCEPTIONS as it was
> the case
> before the introduction of Boost.Exception.

Nothing wrong with this idea. It would address the situation where multiple
libraries are re-implenting the same functionaliy to avoid the extra
dependency.
(I'm not all that crazy about the name - maybe
boost::maybe_throw_exception).
So I'm on board with this if we can't get a concensus on fixing the root
problem.

Robert Ramey

Robert Ramey

unread,
Jun 21, 2012, 7:56:29 PM6/21/12
to bo...@lists.boost.org
Emil Dotchevski wrote:
> On Thu, Jun 21, 2012 at 10:12 AM, Robert Ramey <ra...@rrsd.com> wrote:
>
>> a) boost::throw_exception would be deprecated. (not changed)

> I'm yet to see a problem identified with boost::throw_exception, in
> terms
> of anything at all -- speed, space, build times, whatever.

lol

> Removing functionality from a function breaks code. What is the pain
> you want to alleviate, that justifies deprecation?

the pain would be miniscule. it would result in a trivial compile
error which would take only a couple of minutes to fix. To me
this is a small price to pay to address that the problem with
gratuitous dependency extension. I realize you (and others)
don't see this is a problem - we just have to agree to disagree on this.

Robert Ramey

Nevin Liber

unread,
Jun 21, 2012, 7:05:41 PM6/21/12
to bo...@lists.boost.org
On 20 June 2012 19:19, Robert Ramey <ra...@rrsd.com> wrote:

> > Here's the *real* situation: Welcome to software development.
>
> True - it's bad enough already - So let's agree not to make it worse
> if we can avoid it.
>

Define "worse". There are multiple conflicting goals. As I pointed out
from the FAQ:

"Many of the Boost libraries are actively maintained and improved, so
backward compatibility with prior version isn't always possible."


> "It's not going to be perfect anyway, so don't sweat the small stuff"
>

Of course we should strive for perfection (even if we can't achieve it),
and sweat the small stuff.

Now define "perfection". Perfection != 100% backwards compatible. As I
said before: "While the bar on changing functionality and/or interfaces is
high, it isn't (and never has been, as far as I know) absolute (and it
isn't even as high as the C++ standard, nor should it be)."

Good practices can reduce (but not eliminate) accidental risk., but ultimately,
one has to balance risk of breakage vs. enhancement value.
--
Nevin ":-)" Liber <mailto:ne...@eviloverlord.com> (847) 691-1404

Emil Dotchevski

unread,
Jun 21, 2012, 7:16:19 PM6/21/12
to bo...@lists.boost.org
On Thu, Jun 21, 2012 at 4:56 PM, Robert Ramey <ra...@rrsd.com> wrote:

> Emil Dotchevski wrote:
> > On Thu, Jun 21, 2012 at 10:12 AM, Robert Ramey <ra...@rrsd.com> wrote:
> >
> >> a) boost::throw_exception would be deprecated. (not changed)
>
> > I'm yet to see a problem identified with boost::throw_exception, in
> > terms
> > of anything at all -- speed, space, build times, whatever.
>
> lol
>

Yes. That. :)


> > Removing functionality from a function breaks code. What is the pain
> > you want to alleviate, that justifies deprecation?
>
> the pain would be miniscule. it would result in a trivial compile
> error which would take only a couple of minutes to fix. To me
> this is a small price to pay to address that the problem with
> gratuitous dependency extension. I realize you (and others)
> don't see this is a problem - we just have to agree to disagree on this.
>

Oh, you can disagree, but this does not warrant an action, much less an
action that breaks code. For that, you need facts rather than rhetoric and
unsubstantiated claims.

Dave Abrahams

unread,
Jun 21, 2012, 8:32:26 PM6/21/12
to bo...@lists.boost.org

on Wed Jun 20 2012, Emil Dotchevski <emildotchevski-AT-gmail.com> wrote:

> On Wed, Jun 20, 2012 at 4:56 PM, Robert Ramey <ra...@rrsd.com> wrote:
>
>> Emil Dotchevski wrote:
>> > On Wed, Jun 20, 2012 at 2:55 PM, Robert Ramey <ra...@rrsd.com> wrote:
>>
>> > It is clear that you don't approve of the current definition of
>> > boost::throw_exception. That's fine, you don't have to use it, but if
>> > you want to criticize it, it'd help if you first understand it.
>> > Otherwise you end up making unsubstantiated claims, rather than
>> > pointing out real problems.
>>
>> lol - I haven't critcised boost exception. I only understand it in
>> the very vaguest terms. I've said this in as many ways as I can
>> think of. I don't know what else to do.
>>
>
> I'm confused. I thought you were complaining about build times and
> dependencies.
>
> I mean, if there is a problem with boost::throw_exception or any other part
> of Boost Exception, I'd like to know about it.

Attempting to break a deadlock here...

It seems clear to me from his posts that Robert wants to talk about the
process and has forgotten any specifics about actual problems. It seems
clear to me from your posts that you are most concerned with actual
problems. Since he doesn't have the information, why not take his
suggestion and search the lists for problems involving throw_exception
and serialization? Seems like the only way for you to make progress.

I'm not sure how to create progress for Robert, unfortunately.

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

Emil Dotchevski

unread,
Jun 21, 2012, 11:39:46 PM6/21/12
to bo...@lists.boost.org
On Thu, Jun 21, 2012 at 5:32 PM, Dave Abrahams <da...@boostpro.com> wrote:

> Attempting to break a deadlock here...
>
> It seems clear to me from his posts that Robert wants to talk about the
> process and has forgotten any specifics about actual problems. It seems
> clear to me from your posts that you are most concerned with actual
> problems. Since he doesn't have the information, why not take his
> suggestion and search the lists for problems involving throw_exception
> and serialization?


I don't need to search, I remember very well. :)

In its initial release (1.36), Boost Exception did not support
BOOST_NO_RTTI configurations, which seemed reasonable because most
compilers require RTTI for exception handling. The workaround was to
#define BOOST_EXCEPTION_DISABLE under BOOST_NO_RTTI. A permanent fix was
committed to trunk two weeks later, and released with 1.37.

Faced with the initial problem, Robert's knee-jerk reaction was to not call
boost::throw_exception at all. He changed Boost Serialization, making it
incompatible with all previous releases under BOOST_NO_EXCEPTIONS.

Someone pointed out Robert's mistake, which he corrected, but not before it
got out with the following Boost release (1.37), in which Boost
Serialization had his flawed (and unnecessary) workaround, requiring
BOOST_NO_EXCEPTIONS users of Boost Serialization to make changes in their
code. They had to revert those changes for 1.38.

That was the end of it (or so I thought.)

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Robert Ramey

unread,
Jun 22, 2012, 2:52:15 AM6/22/12
to bo...@lists.boost.org
Nevin Liber wrote:
> Good practices can reduce (but not eliminate) accidental risk., but
> ultimately, one has to balance risk of breakage vs. enhancement value.

Your missing something key here. This injection of a gratuitous
dependency wasn't any way necessary. Boost exception could
have just as easily used it's own name for this function rather
than hijacking an existing one which had a different purpose.
This would have been better than, and if fact it would be better
now, even though now it would be a "breaking change"

This "breaking change was in no way necessary. I think I've tried
to point that out.

Robert Ramey

Robert Ramey

unread,
Jun 22, 2012, 2:57:25 AM6/22/12
to bo...@lists.boost.org
Emil Dotchevski wrote:
> I don't need to search, I remember very well. :)
>
> In its initial release (1.36), Boost Exception did not support
> BOOST_NO_RTTI configurations, which seemed reasonable because most
> compilers require RTTI for exception handling.

wow- that's something I never knew

>The workaround was to
> #define BOOST_EXCEPTION_DISABLE under BOOST_NO_RTTI. A permanent fix
> was committed to trunk two weeks later, and released with 1.37.

> Faced with the initial problem, Robert's knee-jerk reaction was to
> not call boost::throw_exception at all. He changed Boost
> Serialization, making it incompatible with all previous releases
> under BOOST_NO_EXCEPTIONS.

> Someone pointed out Robert's mistake, which he corrected, but not
> before it got out with the following Boost release (1.37), in which
> Boost Serialization had his flawed (and unnecessary) workaround,
> requiring
> BOOST_NO_EXCEPTIONS users of Boost Serialization to make changes in
> their code. They had to revert those changes for 1.38.

Well, I remember it all very differently. Not that it matters.

Robert Ramey

Robert Ramey

unread,
Jun 22, 2012, 2:58:16 AM6/22/12
to bo...@lists.boost.org
Dave Abrahams wrote:
>> I mean, if there is a problem with boost::throw_exception or any
>> other part of Boost Exception, I'd like to know about it.
>
> Attempting to break a deadlock here...
>
> It seems clear to me from his posts that Robert wants to talk about
> the process and has forgotten any specifics about actual problems.
> It seems clear to me from your posts that you are most concerned with
> actual problems.

> Since he doesn't have the information, why not take
> his suggestion and search the lists for problems involving
> throw_exception and serialization?

> Seems like the only way for you to make progress.

> I'm not sure how to create progress for Robert, unfortunately.

lol - then it doesn't matter as it seems I'm (almost) the only one
that is concerned by this.

The problem was the gratuitious inclusion of a new
dependency. The extent/nature of any problem it created or didn't
create is not relevant here. Just the injection of a new body
of code which replaced two lines and added no functionality
used/needed by the serialization library makes the any library
which used boost::throw_exception "bigger" for no reason.
It makes the library more "fragil". It means I have I a new place
to look if something needs looking into. etc.etc.

Sorry, I just can't understand why anyone fails to see this point.

So we'll just move on as Vicente suggested. That will
be satisfactory from my standpoint.

Robert Ramey

Daniel James

unread,
Jun 22, 2012, 2:48:06 AM6/22/12
to bo...@lists.boost.org
On 22 June 2012 04:39, Emil Dotchevski <emildot...@gmail.com> wrote:
>
> In its initial release (1.36), Boost Exception did not support
> BOOST_NO_RTTI configurations, which seemed reasonable because most
> compilers require RTTI for exception handling. The workaround was to
> #define BOOST_EXCEPTION_DISABLE under BOOST_NO_RTTI. A permanent fix was
> committed to trunk two weeks later, and released with 1.37.

If we actually want to improve the process, that suggests to me that
it'd be useful to have at least one tester running with rtti disabled
(and perhaps another with exceptions disabled) and that we might want
to reconsider point releases, which is hopefully easier with a
modularised git setup.

Emil Dotchevski

unread,
Jun 22, 2012, 3:10:04 AM6/22/12
to bo...@lists.boost.org
On Thu, Jun 21, 2012 at 11:58 PM, Robert Ramey <ra...@rrsd.com> wrote:

> Dave Abrahams wrote:
> > I'm not sure how to create progress for Robert, unfortunately.
>
> lol - then it doesn't matter as it seems I'm (almost) the only one
> that is concerned by this.
>
> The problem was the gratuitious inclusion of a new
> dependency. The extent/nature of any problem it created or didn't
> create is not relevant here. Just the injection of a new body
> of code which replaced two lines and added no functionality
> used/needed by the serialization library makes the any library
> which used boost::throw_exception "bigger" for no reason.
>

You seem to think that if a library doesn't benefit from calling
boost::throw_exception, then the call to boost::throw_exception can't
benefit the users of the library.

As a matter of fact this is not true. There are practical benefits (to
Boost users) from what you call "bigger", while the downside remains
abstract.


> It makes the library more "fragil". It means I have I a new place
> to look if something needs looking into. etc.etc.
>
> Sorry, I just can't understand why anyone fails to see this point.
>

Because you keep talking in the abstract. You'll have better luck if you
point out a practical issue with boost::throw_exception.


> So we'll just move on as Vicente suggested. That will
> be satisfactory from my standpoint.
>

Your satisfaction notwithstanding, there needs to be a reason to change how
Boost deals with exceptions.

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Vicente J. Botet Escriba

unread,
Jun 22, 2012, 2:30:51 AM6/22/12
to bo...@lists.boost.org
Le 22/06/12 01:55, Robert Ramey a écrit :
> Vicente J. Botet Escriba wrote:
>>
>> Hi Robert,
>>
>> I propose you a different thing. Instead of changing again the name of
>> boost::throw_exception, we can add something like
>> boost::throw_strict_exception that will either throw the given
>> exception or no throw at all depending on BOOST_NO_EXCEPTIONS as it was
>> the case
>> before the introduction of Boost.Exception.
> Nothing wrong with this idea. It would address the situation where multiple
> libraries are re-implenting the same functionaliy to avoid the extra
> dependency.
> (I'm not all that crazy about the name - maybe
> boost::maybe_throw_exception).
> So I'm on board with this if we can't get a concensus on fixing the root
> problem.
>
I don't see any other way if backward compatibility must be preserved ;-)


I like the maybe_ prefix. It states clearly the intent of the function.
What about boost::maybe_throw(e)? It is shorter and closer to the
throw(e) it is a replacement of.
Could you see if the authors that have its own throw_exception version
share the approach?

Best,
Vicente

Emil Dotchevski

unread,
Jun 22, 2012, 3:16:45 AM6/22/12
to bo...@lists.boost.org
On Thu, Jun 21, 2012 at 11:48 PM, Daniel James <dnl...@gmail.com> wrote:

> On 22 June 2012 04:39, Emil Dotchevski <emildot...@gmail.com> wrote:
> >
> > In its initial release (1.36), Boost Exception did not support
> > BOOST_NO_RTTI configurations, which seemed reasonable because most
> > compilers require RTTI for exception handling. The workaround was to
> > #define BOOST_EXCEPTION_DISABLE under BOOST_NO_RTTI. A permanent fix was
> > committed to trunk two weeks later, and released with 1.37.
>
> If we actually want to improve the process, that suggests to me that
> it'd be useful to have at least one tester running with rtti disabled
> (and perhaps another with exceptions disabled) and that we might want
> to reconsider point releases, which is hopefully easier with a
> modularised git setup.
>

Yes, this is exactly why the problem wasn't detected before the release: we
don't test that configuration.

RTTI is particularly tricky because it isn't a simple on-off thing, there's
BOOST_NO_RTTI and a separate BOOST_NO_TYPEID, plus there is an implicit
link between RTTI and exception handling in some (most?) compilers.

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Stewart, Robert

unread,
Jun 22, 2012, 8:23:03 AM6/22/12
to bo...@lists.boost.org
Robert Ramey wrote:
> Dave Abrahams wrote:
> >> I mean, if there is a problem with boost::throw_exception or
> >> any other part of Boost Exception, I'd like to know about
> >> it.
> >
> > It seems clear to me from his posts that Robert wants to
> > talk about the process and has forgotten any specifics about
> > actual problems.
> >
> The problem was the gratuitious inclusion of a new dependency.

Emil has described repeatedly why the change was not gratuitous. That you fail to recognize the value in the change does not make it gratuitous.

I looked at a recent boost/throw_exception.hpp. It includes boost/exception/detail/attribute_noreturn.hpp. That creates a dependency inversion that is unfortunate. That is, a top-level header file depends upon a header file of a library's files. That header is very short and has nothing Boost.Exception specific, so the code could be moved into boost/throw_exception.hpp or boost/detail/attribute_noreturn.hpp, for example.

The header also conditionally includes the non-trivial boost/exception/exception.hpp, another dependency inversion, which defines many types and functions, and includes some inline function definitions:

boost::exception_detail::refcount_ptr
boost:: error_info
boost::exception
boost::exception_detail::error_info_base
boost::exception_detail::type_info_
boost::exception_detail::error_info_container
boost::exception_detail::get_info
boost::exception_detail::get_diagnostic_information()
boost::exception_detail::copy_boost_exception()
boost::exception_detail::set_info()
boost::exception_detail::error_info_injector
boost::enable_error_info()
boost::exception_detail::clone_base
boost::exception_detail::clone_impl
boost::enable_current_exception()

If BOOST_EXCEPTION_DISABLE is not defined, then boost::throw_exception() tacks on Boost.Exception features to the exception being thrown.

This is a non-trivial set of changes to make to the top-level header. I didn't follow the discussion at the time, but I'll presume there was a lot of discussion about the type and extent of these changes and that it was considered a good idea. In hindsight, I agree with Robert's assertion that there should have been a replacement function, boost::exception::throw_exception() or similar, to introduce the new functionality. Whether the existing function needed to be deprecated is a separate issue. The result is that libraries could knowingly choose the new version, and a dependency on Boost.Exception, or, if warranted, stick with the old.

As things now stand, if there is good reason to avoid the new version, it can only be done by defining BOOST_EXCEPTION_DISABLE, which affects an entire build.

> The extent/nature of any problem it created or didn't create is
> not relevant here. Just the injection of a new body of code
> which replaced two lines and added no functionality used/needed
> by the serialization library makes the any library which used
> boost::throw_exception "bigger" for no reason.

The issue you're raising, as I understand it, is dependency inversion: the top-level header brings a dependency on Boost.Exception.

> It makes the library more "fragil". It means I have I a new
> place to look if something needs looking into. etc.etc.

As Nevin pointed out, your code will always be subject to the changes in those libraries on which it depends. The more dependencies you introduce, the more fragile your code becomes, but there's a great deal of benefit to reuse, too. The only issue in this case is that one can reasonably expect a top-level header to avoid dependencies on libraries.

> So we'll just move on as Vicente suggested. That will be
> satisfactory from my standpoint.

That is the only way forward, if there is good reason to avoid the now longstanding changes to boost::throw_exception(). However, you should work with Emil to be sure you correctly and fully understand the issues before deciding that you cannot accept boost::throw_exception() as is. (I don't pretend to know what your concerns are. I just don't want to see a new throw_exception() variant if there isn't a compelling reason, and I don't consider your fragility argument compelling in this case.)

_____
Rob Stewart robert....@sig.com
Software Engineer using std::disclaimer;
Dev Tools & Components
Susquehanna International Group, LLP http://www.sig.com



________________________________

IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Fabio Fracassi

unread,
Jun 22, 2012, 11:30:00 AM6/22/12
to bo...@lists.boost.org
On 6/22/12 8:58 AM, Robert Ramey wrote:

> lol - then it doesn't matter as it seems I'm (almost) the only one
> that is concerned by this.
>
> The problem was the gratuitious inclusion of a new
> dependency. The extent/nature of any problem it created or didn't
> create is not relevant here.

Yes it is, because in reality boost exception solves problems for the
users of any library that uses it. When using boost exception I can
safely let exceptions escape threads and have them rethrown in the
starting thread, for instance.

> Just the injection of a new body
> of code which replaced two lines and added no functionality
> used/needed by the serialization library makes the any library
> which used boost::throw_exception "bigger" for no reason.

It has a real and important reason, because it unifies boost exception
handling, nearly for free. The few boost libraries which do not use it,
serialization most notably, cause trouble because they need extra care
to make exception handling well behaved.

> It makes the library more "fragil".

No, it gave your users more functionality in an area of which you were
not even aware.


> It means I have I a new place
> to look if something needs looking into. etc.etc.

It is a shoulder (not quite a giants, but still) to stand on, which
gives you a higher reach!


regards

Fabio

Roger Martin

unread,
Jun 22, 2012, 11:55:45 AM6/22/12
to bo...@lists.boost.org
On 06/22/2012 11:30 AM, Fabio Fracassi wrote:
>
> Yes it is, because in reality boost exception solves problems for the
> users of any library that uses it. When using boost exception I can
> safely let exceptions escape threads and have them rethrown in the
> starting thread, for instance.
I use this heavily and it works great while simplifying code
considerably. Got rid of bubbling errors and multiple ways to do
exceptions/errors. When the unified boost exceptions came into
existence tried them and immediately found a difference in code style,
code size, readability and code maintenance. Boost threads, smart
pointers, unified exceptions, timers, etc. improved C++ multi-thread
programming for me considerably. And now boost threads and exceptions
are working with the same code on Windows, Mac and Linux with all gnu
compile.
>
> ...
> It has a real and important reason, because it unifies boost exception
> handling, nearly for free. The few boost libraries which do not use
> it, serialization most notably, cause trouble because they need extra
> care to make exception handling well behaved.
Catching and handling is now so much better it is good to reflect on
what was achieved since ~1.38

Robert Ramey

unread,
Jun 22, 2012, 1:30:13 PM6/22/12
to bo...@lists.boost.org
Stewart, Robert wrote:
> Robert Ramey wrote:
>> Dave Abrahams wrote:
>>>> I mean, if there is a problem with boost::throw_exception or
>>>> any other part of Boost Exception, I'd like to know about
>>>> it.
>>>
>>> It seems clear to me from his posts that Robert wants to
>>> talk about the process and has forgotten any specifics about
>>> actual problems.
>>>
>> The problem was the gratuitious inclusion of a new dependency.
>
> Emil has described repeatedly why the change was not gratuitous.
> That you fail to recognize the value in the change does not make it
> gratuitous.

If you like you can substitute the term "unnecessary"

> I looked at a recent boost/throw_exception.hpp. ....
...
> The issue you're raising, as I understand it, is dependency
> inversion: the top-level header brings a dependency on
> Boost.Exception.

That's it.

>> It makes the library more "fragil". It means I have I a new
>> place to look if something needs looking into. etc.etc.
>
> As Nevin pointed out, your code will always be subject to the changes
> in those libraries on which it depends.

LOL - that's precisely why I don't want to see unnecessary
dependencies introduced. Especially when I'm not looking.

> The more dependencies you
> introduce, the more fragile your code becomes, but there's a great
> deal of benefit to reuse, too. The only issue in this case is that
> one can reasonably expect a top-level header to avoid dependencies on
> libraries.

Personally I wouldn't say it's the only issue. But I'm glad we can
agree that it's its a BIG issue.

>> So we'll just move on as Vicente suggested. That will be
>> satisfactory from my standpoint.

> That is the only way forward, if there is good reason to avoid the
> now longstanding changes to boost::throw_exception().

And how is that to be determined? Who would do that work?

> However, you should work with Emil to be sure you correctly and
> fully understand the issues before deciding that you cannot accept
> boost::throw_exception() as is.

Ahhh - this is the rub.

> (I don't pretend to know what your concerns are.)

LOL - you described them very well in your previous post.
And you've supported your argument for my (general/abstract?)
concerns with a meticulous analysis of the current implementation of
boost::throw as particular example. Thank you for that.

> I just don't want to see a new throw_exception()
> variant if there isn't a compelling reason, and I don't consider your
> fragility argument compelling in this case.)

You've looked into this - did you see any "compelling reason" to
inject this code into the serialization or any other library?

Robert Ramey

Stewart, Robert

unread,
Jun 22, 2012, 1:10:32 PM6/22/12
to bo...@lists.boost.org
Robert Ramey wrote:
> Stewart, Robert wrote:
> > Robert Ramey wrote:
> >> Dave Abrahams wrote:
>
> > I looked at a recent boost/throw_exception.hpp.
> [snip]
> > The issue you're raising, as I understand it, is dependency
> > inversion: the top-level header brings a dependency on
> > Boost.Exception.
>
> That's it.

OK, good. I'm glad we've succinctly and clearly identified your concern. That means there's an opportunity to make progress and set policy.

> >> It makes the library more "fragil". It means I have I a
> >> new place to look if something needs looking into. etc.
> >
> > As Nevin pointed out, your code will always be subject to the
> > changes in those libraries on which it depends.
>
> LOL - that's precisely why I don't want to see unnecessary
> dependencies introduced. Especially when I'm not looking.

I get that. If the change was unnecessary, then it adds a dependency that complicates your maintenance. However, there's still the question of whether the dependency was necessary. You're convinced it wasn't, I know.

> >> So we'll just move on as Vicente suggested. That will be
> >> satisfactory from my standpoint.
>
> > That is the only way forward, if there is good reason to
> > avoid the now longstanding changes to
> > boost::throw_exception().
>
> And how is that to be determined? Who would do that work?

Clearly, those (you) with a concern would make a proposal, elicit discussion of the idea and proposed solution, then, if deemed acceptable, determine what sort of review process is warranted.

> > However, you should work with Emil to be sure you correctly
> > and fully understand the issues before deciding that you
> > cannot accept boost::throw_exception() as is.
>
> Ahhh - this is the rub.

Yes, and it's a very important first step.

> > (I don't pretend to know what your concerns are.)
>
> LOL - you described them very well in your previous post.

I'm not so sure. You've gone to some lengths to avoid the Boost.Exception dependency and, I presume, it was not motivated simply because you did not want Serialization being dependent upon Exception.

> > I just don't want to see a new throw_exception() variant
> > if there isn't a compelling reason, and I don't consider
> > your fragility argument compelling in this case.)
>
> You've looked into this - did you see any "compelling reason"
> to inject this code into the serialization or any other
> library?

I don't know what benefits it may bring to Serialization and that's the crux of the matter. Roger Martin and Fabio Fracassi have both described the value they get from Boost.Exception and, presumably, from boost::throw_exception(), that they don't get from Serialization precisely because you have avoided the dependency. It is for reasons like those that I suggest reevaluating whether Serialization should accept boost::throw_exception() as is and avoid the fork.


_____
Rob Stewart robert....@sig.com
Software Engineer using std::disclaimer;
Dev Tools & Components
Susquehanna International Group, LLP http://www.sig.com


________________________________

IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Daniel James

unread,
Jun 22, 2012, 1:25:33 PM6/22/12
to bo...@lists.boost.org
On 22 June 2012 18:30, Robert Ramey <ra...@rrsd.com> wrote:
> Stewart, Robert wrote:
>
>>  The more dependencies you
>> introduce, the more fragile your code becomes, but there's a great
>> deal of benefit to reuse, too.  The only issue in this case is that
>> one can reasonably expect a top-level header to avoid dependencies on
>> libraries.
>
> Personally I wouldn't say it's the only issue.  But I'm glad we can
> agree that it's its a BIG issue.

There are a lot of headers violating your rule. What problems has it caused?

John Maddock

unread,
Jun 22, 2012, 1:53:04 PM6/22/12
to bo...@lists.boost.org
>> The more dependencies you
>> introduce, the more fragile your code becomes, but there's a great
>> deal of benefit to reuse, too. The only issue in this case is that
>> one can reasonably expect a top-level header to avoid dependencies on
>> libraries.
>
> Personally I wouldn't say it's the only issue. But I'm glad we can
> agree that it's its a BIG issue.
>
>There are a lot of headers violating your rule. What problems has it
>caused?

I suspect that's true.

Here's another point then - if the two small headers of Boost.Exception upon
which throw_exception depends were moved into boost/detail/ - would that
make you happier? I don't see it makes any difference myself: other perhaps
than making a declaration that these are and will remain lightweight
includes, and won't suddenly dump a whole bunch of other Boost.Exception
code into your files.

John.

John Maddock

unread,
Jun 22, 2012, 2:11:14 PM6/22/12
to bo...@lists.boost.org
>> I just don't want to see a new throw_exception()
>> variant if there isn't a compelling reason, and I don't consider your
>> fragility argument compelling in this case.)
>
> You've looked into this - did you see any "compelling reason" to
> inject this code into the serialization or any other library?

Let's try and give some examples:

1) Unlike "regular" exception objects, objects which derive from
boost::exception can have additional information added to them either at the
call site, or later in the call stack. Consider this case: user opens a
std::fstream and passes the object to a serialization method which then
throws. Currently you may get some information about the failure, but not
the file name because serialization doesn't know what that is (as far as I
know). However, with Boost.Exception support, the calling code can annotate
the already thrown exception, retaining all the information it contains, but
adding whatever extra information (file name for example) is available. See
http://www.boost.org/doc/libs/1_49_0/libs/exception/doc/tutorial_transporting_data.html.
2) As others have already mentioned, Boost.Exception allows arbitrary
exception objects to be cloned, amongst other things, this allows exceptions
to propagate across threads. For example if a serialization routine is run
as a future (quite a reasonable goal), then it would allow exceptions thrown
during serialization in the worker thread, to be re-thrown in the calling
thread when the result of the future is acquired. See
http://www.boost.org/doc/libs/1_49_0/libs/exception/doc/tutorial_exception_ptr.html.
3) Boost.Exception provides additional information about from where the
exception was thrown (file and line number etc), this can be extremely
useful in diagnostic situations when an exception was "unexpected". See
http://www.boost.org/doc/libs/1_49_0/libs/exception/doc/tutorial_diagnostic_information.html.

For me, I've only used (3), but when you need it it's very useful. Both (1)
and (2) look like killer use cases to me - not for you - for your users.

HTH, John.

Dave Abrahams

unread,
Jun 22, 2012, 2:24:53 PM6/22/12
to bo...@lists.boost.org

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

> Dave Abrahams wrote:
>>> I mean, if there is a problem with boost::throw_exception or any
>>> other part of Boost Exception, I'd like to know about it.
>>
>> Attempting to break a deadlock here...
>>
>
>> It seems clear to me from his posts that Robert wants to talk about
>> the process and has forgotten any specifics about actual problems.
>> It seems clear to me from your posts that you are most concerned with
>> actual problems.
>
>> Since he doesn't have the information, why not take
>> his suggestion and search the lists for problems involving
>> throw_exception and serialization?
>
>> Seems like the only way for you to make progress.
>
>> I'm not sure how to create progress for Robert, unfortunately.
>
> lol - then it doesn't matter as it seems I'm (almost) the only one
> that is concerned by this.
>
> The problem was the gratuitious inclusion of a new
> dependency.

I wish you would stop using the term "gratuitous" here. I don't have
any position on who's right or what's better, but clearly some people
thought the inclusion of this dependency had a purpose and wasn't
totally unnecessary.

> The extent/nature of any problem it created or didn't create is not
> relevant here. Just the injection of a new body of code which
> replaced two lines and added no functionality used/needed by the
> serialization library makes the any library which used
> boost::throw_exception "bigger" for no reason. It makes the library
> more "fragil". It means I have I a new place to look if something
> needs looking into. etc.etc.
>
> Sorry, I just can't understand why anyone fails to see this point.

Because, while it's true that it has those effects, that sort of thing
happens all the time, and most of us see no reasonable way of stopping
it without severely constraining Boost development.

Don't you regularly "inject new bodies of code" into Boost.Serialization
that "replace lines and add no functionality used/needed by" Boost.MPI?

Don't you expect the author of type_traits to do the same thing?

> So we'll just move on as Vicente suggested. That will
> be satisfactory from my standpoint.

I'm happy to move on if you're really going to put this behind you. If
you won't truly be able to, then we should keep talking until we can all
understand each other because this is at least the 2nd time we've had a
long argument about it and it would be a shame to have to go over the
same ground again.

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


Dave Abrahams

unread,
Jun 22, 2012, 2:33:34 PM6/22/12
to bo...@lists.boost.org

on Fri Jun 22 2012, Daniel James <dnljms-AT-gmail.com> wrote:

> On 22 June 2012 18:30, Robert Ramey <ra...@rrsd.com> wrote:
>> Stewart, Robert wrote:
>>
>>>  The more dependencies you
>>> introduce, the more fragile your code becomes, but there's a great
>>> deal of benefit to reuse, too.  The only issue in this case is that
>>> one can reasonably expect a top-level header to avoid dependencies on
>>> libraries.
>>
>> Personally I wouldn't say it's the only issue.  But I'm glad we can
>> agree that it's its a BIG issue.
>
> There are a lot of headers violating your rule.

Most notably, there are plenty of aggregate headers that do this.

> What problems has it caused?

Good question. We do have two problematic dependency loops in Boost, but
it's not caused by this sort of header structure:

http://f.cl.ly/items/343N460u3b3039091C0g/deps.pdf

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

Robert Ramey

unread,
Jun 22, 2012, 3:41:18 PM6/22/12
to bo...@lists.boost.org
Daniel James wrote:
> On 22 June 2012 18:30, Robert Ramey <ra...@rrsd.com> wrote:
>> Stewart, Robert wrote:
>>
>>> The more dependencies you
>>> introduce, the more fragile your code becomes, but there's a great
>>> deal of benefit to reuse, too. The only issue in this case is that
>>> one can reasonably expect a top-level header to avoid dependencies
>>> on libraries.
>>
>> Personally I wouldn't say it's the only issue. But I'm glad we can
>> agree that it's its a BIG issue.
>
> There are a lot of headers violating your rule.

assuming that's true, it's a bad idea there as well.

> What problems has it caused?

lol - this discussion for one.

But your comments are sincere and really deserve a more serious answer
so I'll try to supply one.

TL;DR

Someone comes up with some idea for a program/application/library
or whatever. This idea is meant to solve some problem that this
person has in mind. At this point - any subsequent point, this idea
will move in two directions

a) It will become more specific and narrowed in scope and evolve
into a very clear concept what can easily be grasped as to what it's
function is. We have great examples of this in boost - shared_ptr
static_assert. Deeper understanding

How to recognize a)
1) You use it or incorporate into your app in a very short time
because it's easy to understand what it does and how to use it.
2) you use it and you forget you used it because it caused no
surprises.
3) It works for years without a hassle
4) it saves total work - rather than expanding it.
5) if anything breaks - its easy to find the cause and the
person who should fix it.

b) It can evolve into a more amorpheous and all encompassing idea
that looks more like a "bag of features" rather than a coherent concept
which one can understand immediately and systematically
unwrap to understand at a more detailed level. We have some
software in boost which exmplefies this.

How to recognise b)
1) It might look simple to use, but turns out to consume a lot of time
when you try to use it. (I love it when a salesman demonstrates how simple
something is to use and I take it home - and damned if I'm not mystified
by it!)
2) It's has surprising behavior
3) It breaks when you don't expect it
4) if you complain - it's "your fault" because you didn't understand how
to use it, didn't read the docs, didn't look the code or whatever.
5) It adds total work rather than diminishing it.
6) it becomes hard to determine who is responsable for problems
when they occur.

Of course these are idealized descriptions no library/application will
fall 100% in either camp. This description applies to a lot more
stuff than just software - see the book "The design of everyday
things".

Even if the idea is seems clearly defined, as time goes on there is
a huge amount of pressure to add "just one feature" because
someone would find it useful. The result is that the original idea morphs
from a clearly defined purpose to some sort of .... well hard to describe.
The project start's to suffer from the symptoms in b) above.

Projects in the "b)" category tend to grow and die of a combination
of obesity, weakness, lack of direction. Basically they tend ot become
victims of their own success.

I realize this is "just one feature which a lot of people would find useful"
but who speaks for the people who don't find it useful? I do. You're
thinkng this is a one time special case. But it's not. I fight a constant
running battle to keep the serialzation library from evolving into something
that is unmaintainble, overly bloated, harder to understand and use, etc.
I can't tell you how many times I've had to disappoint someone who
feels they need this "one more tihng".

So now maybe you can understand how I can object to having this
"great feature" injected into the library without my knowing about it.

I'm not intending to be the "savanorla" of boost, C++, or software
developement practices. I just happened to be the person at the scene
of this particular accident.

Robert Ramey

Robert Ramey

unread,
Jun 22, 2012, 3:55:27 PM6/22/12
to bo...@lists.boost.org
Fabio Fracassi wrote:
> On 6/22/12 8:58 AM, Robert Ramey wrote:
>
>> The problem was the gratuitious inclusion of a new
>> dependency. The extent/nature of any problem it created or didn't
>> create is not relevant here.
>
> Yes it is, because in reality boost exception solves problems for the
> users of any library that uses it. When using boost exception I can
> safely let exceptions escape threads and have them rethrown in the
> starting thread, for instance.

well, not every application uses threads. Really, I don't think anyone
can say "solves problems for ANY library which uses it." without
knowing what the application is.

>> Just the injection of a new body
>> of code which replaced two lines and added no functionality
>> used/needed by the serialization library makes the any library
>> which used boost::throw_exception "bigger" for no reason.
>
> It has a real and important reason, because it unifies boost exception
> handling, nearly for free. The few boost libraries which do not use
> it, serialization most notably, cause trouble because they need extra
> care to make exception handling well behaved.

Is there any reason you can't trap any exception from a library
and rethrow it using boost.exception in your own application?

>> It makes the library more "fragil".
>
> No, it gave your users more functionality in an area of which you were
> not even aware.

That's exactly what makes it more fragil. From my standpoint, I'm on the
hook for any problem which occurs in the injected code. Code actually
have no idea what it does.

>> It means I have I a new place
>> to look if something needs looking into. etc.etc.
>
> It is a shoulder (not quite a giants, but still) to stand on, which gives
> you a higher reach!

Gives YOU a higher reach - at my expense.

I will say you've given a rousing endorsement of boost exception
and a good case for it's merits.

I'm not convinced that you've all the applications of boost libraries
outside
your problem domain. If someone wanted to take a serious look at the
something
the serialization (or other library) and propose some enhance me - maybe via
a policy argument or whatever and create a TRAC item, that would be one
thng. But for one person to inject code/depency into a separate library
because
he "knows better what users need" isn't a great idea (unless he wants to
take
over maintainence of the library - which of course would be a whole
different thing.

Robert Ramey

Robert Ramey

unread,
Jun 22, 2012, 4:17:36 PM6/22/12
to bo...@lists.boost.org
John Maddock wrote:
>>> I just don't want to see a new throw_exception()
>>> variant if there isn't a compelling reason, and I don't consider
>>> your fragility argument compelling in this case.)
>>
>> You've looked into this - did you see any "compelling reason" to
>> inject this code into the serialization or any other library?
>
> Let's try and give some examples:

I really didn't want to get is these specifics. But you've sucked me in.

> 1) Unlike "regular" exception objects, objects which derive from
> boost::exception can have additional information added to them either
> at the call site, or later in the call stack. Consider this case:
> user opens a std::fstream and passes the object to a serialization
> method which then throws. Currently you may get some information
> about the failure, but not the file name because serialization
> doesn't know what that is (as far as I know). However, with
> Boost.Exception support, the calling code can annotate the already
> thrown exception, retaining all the information it contains, but
> adding whatever extra information (file name for example) is
> available. See
> http://www.boost.org/doc/libs/1_49_0/libs/exception/doc/tutorial_transporting_data.html.

Why does the serialization library have to include code from boost
exception in order to do this?

You can use boost exception at the same place, catch
the standard exception that the serialization throws, construct you're
own boost exception and continue on.

> 2) As others have already mentioned, Boost.Exception allows arbitrary
> exception objects to be cloned, amongst other things, this allows
> exceptions to propagate across threads. For example if a
> serialization routine is run as a future (quite a reasonable goal),
> then it would allow exceptions thrown during serialization in the
> worker thread, to be re-thrown in the calling thread when the result
> of the future is acquired. See
> http://www.boost.org/doc/libs/1_49_0/libs/exception/doc/tutorial_exception_ptr.html.

again the same question.

> 3) Boost.Exception provides additional information about from where
> the exception was thrown (file and line number etc), this can be
> extremely useful in diagnostic situations when an exception was
> "unexpected". See
> http://www.boost.org/doc/libs/1_49_0/libs/exception/doc/tutorial_diagnostic_information.html.
>
> For me, I've only used (3), but when you need it it's very useful. Both
> (1) and (2) look like killer use cases to me - not for you - for
> your users.

Let me be clear. I don't have any complaint about boost exception per se.

My complaint is the process by which it was inject.

BUT - now you've sucked me into looking at the merits of including it, I
don't
see that it would be of any use. here's typical serialization code:

#include <boost/archiive/binary_iarchive.hpp>
#include <ifstream>
...
f(...){
ifsteam is("my file")
binary_iarchive ia(is);
try {
my_data d;
ia >> d;
}
catch(boost::archive::exception ae){
std::cout << ae.what();
throw(ae) ; // or throw something else
}
return;
}

So if I want to use boost exception I would just write

#include <boost/archiive/binary_iarchive.hpp>
#include <ifstream>
#include <boost/exception/???.hpp>
...

f(...){
ifsteam is("my file")
binary_iarchive ia(is);
try {
my_data d;
ia >> d;
}
catch(boost::archive::exception ae){
std::cout << ae.what();
// I don't know how to use boost::exception insert your own code
here
boost::exception::throw(?)
}
return;
}

I don't see injecting boost::exception into the serialization code changes
this in
any way

Robert Ramey

Robert Ramey

unread,
Jun 22, 2012, 4:36:41 PM6/22/12
to bo...@lists.boost.org
Dave Abrahams wrote:
> on Fri Jun 22 2012, "Robert Ramey" <ramey-AT-rrsd.com> wrote:

>> Sorry, I just can't understand why anyone fails to see this point.
>
> Because, while it's true that it has those effects, that sort of thing
> happens all the time, and most of us see no reasonable way of stopping
> it without severely constraining Boost development.

> Don't you regularly "inject new bodies of code" into
> Boost.Serialization that "replace lines and add no functionality
> used/needed by" Boost.MPI?

No. I don't do this.

I have made some mistakes - particularly in the implementation
of binary_iarchive which have broken other peoples code. But
I assure you this was totally unintentional.

This wouldn't mean that no new code is never added. Natually
one could add a new archive type. But that would only affect
those who conciously chose to use it. But that would of course
that be a different case.

> Don't you expect the author of type_traits to do the same thing?

No. I don't.

If I use something like "is_arithmetic" I expect it's functionality
to not change in the future.

>> So we'll just move on as Vicente suggested. That will
>> be satisfactory from my standpoint.

> I'm happy to move on if you're really going to put this behind you.
> If you won't truly be able to, then we should keep talking until we
> can all understand each other because this is at least the 2nd time
> we've had a long argument about it and it would be a shame to have to
> go over the same ground again.

I'm sympathetic to you view here. It wasn't really resolved before - we
just worked around it. Basically this is what we're going to continue to do
albeit is a less ad hoc way.

I'm really sympathetic to those who see this as a pointless, endlee
argument.
But obviously it's not for those of us involved in it. For the most part
I don't doubt the good intentions and sincerity of those who are
disagreeing with me here. I just think they're wrong and they they have
failed to make a convincing argument that I'm wrong. And I believe
that these "wrong ideas" (my view) make a large negative impact on
software usability and quality. That's why I take pains to try to exclude
them from the serialization library. No Doubt Emil feels the same way
about his ideas. So there can really be no real resolution, we can only
muddle forward - which is not the worst thing we could do.

Robert Ramey

Robert Ramey

unread,
Jun 22, 2012, 4:40:19 PM6/22/12
to bo...@lists.boost.org
Dave Abrahams wrote:
> on Fri Jun 22 2012, Daniel James <dnljms-AT-gmail.com> wrote:
>> There are a lot of headers violating your rule.
>
> Most notably, there are plenty of aggregate headers that do this.

In a previous post, I specifically excluded "convenience headers" from
being considered as "violating" this "rule". They are not at issue here.

Robert Ramey

Nevin Liber

unread,
Jun 22, 2012, 4:13:43 PM6/22/12
to bo...@lists.boost.org
On 22 June 2012 15:40, Robert Ramey <ra...@rrsd.com> wrote:

>
> In a previous post, I specifically excluded "convenience headers" from
> being considered as "violating" this "rule". They are not at issue here.
>

You keep asserting this, but I haven't seen you explain *what* makes the
convenience headers so special that they do not violate your rule.
--
Nevin ":-)" Liber <mailto:ne...@eviloverlord.com> (847) 691-1404

Robert Ramey

unread,
Jun 22, 2012, 5:36:35 PM6/22/12
to bo...@lists.boost.org
Nevin Liber wrote:
> On 22 June 2012 15:40, Robert Ramey <ra...@rrsd.com> wrote:
>
>>
>> In a previous post, I specifically excluded "convenience headers"
>> from being considered as "violating" this "rule". They are not at
>> issue here.

> You keep asserting this, but I haven't seen you explain *what* makes
> the convenience headers so special that they do not violate your rule.

I'm sure of what "my rule" means. But I try to clarify my view.:

I have no complaint or issue with headers whose function is to
contain a list of library headers so that uses can include a bunch
of related headers at with just one include statement. I have
referred to this practice as a "convenience header" which I
believe is common practice on this list.

FWIW I presonally don't like "convenience headers" because I
like to have a better idea of what I'm actually including. But
let's chalk that up to personal taste and not anybody's problem.

The following sort of example

file:boost/throw_exception.hpp
#include <boost/exception/.?.hpp>

is what I'm objecting to. This means that when I my code contains

#include <boost/throw_exception.hpp>

>From reading the code, I don't it to expect to include a whole
'nother library. And that's they way it was before it was changed.
The change created surprises for me - and I just like to minimize
surprises. This is about writing code which does what it looks like
it says it's going to do - no more no less.

Also note that I'm not saying that following the practice I recommend
will solve all problems and avoid all surprises. But it contributes to
diminishing them and also helps keep the program/library scope from
expanding beyond the minimum it needs to be to do the job.

It's not that complicated and I don't think it should be all that
controversial.

Robert Ramey

Emil Dotchevski

unread,
Jun 22, 2012, 7:03:31 PM6/22/12
to bo...@lists.boost.org
On Fri, Jun 22, 2012 at 12:55 PM, Robert Ramey <ra...@rrsd.com> wrote:

> Fabio Fracassi wrote:
> > On 6/22/12 8:58 AM, Robert Ramey wrote:
> >
> >> The problem was the gratuitious inclusion of a new
> >> dependency. The extent/nature of any problem it created or didn't
> >> create is not relevant here.
> >
> > Yes it is, because in reality boost exception solves problems for the
> > users of any library that uses it. When using boost exception I can
> > safely let exceptions escape threads and have them rethrown in the
> > starting thread, for instance.
>
> well, not every application uses threads. Really, I don't think anyone
> can say "solves problems for ANY library which uses it." without
> knowing what the application is.
>

This works the other way around too. A library developer, without knowing
what the application is, shouldn't be preventing the user from using Boost
Exception with the exceptions emitted by the library.

When a library calls boost::throw_exception, this potentially solves
problems for the USERS of the library (depending on the architecture of the
application), even if the library itself doesn't benefit.

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski

unread,
Jun 22, 2012, 7:16:29 PM6/22/12
to bo...@lists.boost.org
On Fri, Jun 22, 2012 at 5:23 AM, Stewart, Robert <Robert....@sig.com>wrote:

> Robert Ramey wrote:
> > Dave Abrahams wrote:
> > >> I mean, if there is a problem with boost::throw_exception or
> > >> any other part of Boost Exception, I'd like to know about
> > >> it.
> > >
> > > It seems clear to me from his posts that Robert wants to
> > > talk about the process and has forgotten any specifics about
> > > actual problems.
> > >
> > The problem was the gratuitious inclusion of a new dependency.
>
> Emil has described repeatedly why the change was not gratuitous. That you
> fail to recognize the value in the change does not make it gratuitous.
>
> I looked at a recent boost/throw_exception.hpp. It includes
> boost/exception/detail/attribute_noreturn.hpp. That creates a dependency
> inversion that is unfortunate.


Obviously this is separated in a header with the prospect of becoming an
official Boost header. OTOH, this functionality didn't exist, which
presumably means that nobody else needs it.

(I do not see the "dependency inversion" as a problem.)

The header also conditionally includes the non-trivial
> boost/exception/exception.hpp, another dependency inversion, which defines
> many types and functions, and includes some inline function definitions
>

Sure, that's what headers do. :)

Pretty much all of this header is implementation details. The bit that
concerns the user is that it's a couple hundred lines of self-contained
code with absolutely no external dependencies.


> If BOOST_EXCEPTION_DISABLE is not defined, then boost::throw_exception()
> tacks on Boost.Exception features to the exception being thrown.
>
> This is a non-trivial set of changes to make to the top-level header.


It's non-trivial in that it enables the library to function.

It's trivial in terms of cost and backwards compatibility.

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Jeffrey Lee Hellrung, Jr.

unread,
Jun 23, 2012, 12:37:47 AM6/23/12
to bo...@lists.boost.org
I took some time to dig up and read some earlier threads on this. Major
deja vu here, yo.

On Wed, Jun 20, 2012 at 2:55 PM, Robert Ramey <ra...@rrsd.com> wrote:

> Jeffrey Lee Hellrung, Jr. wrote:
>
[...]

> > For some
> >> unfathonable reason, the change in boost::throw_exception was
> >> allowed to stand. So these libraries including serialization,
> >> boost.filesystem, and some
> >> others had to creat their own macros to implement the behavior of the
> >> original boost::throw_exception.
> >
>
> > Was actual code broken due to the change,
>
> Well it was noticed because it created problems.
>

> > and, if so, do you remember any examples?
>
> of course not. I suppose you could troll the list if you were
> really interested.
>

I was and I did.

I've found 2 threads which seem to refer to problems observed in
Boost.Serialization due to the Boost.Exception update of
boost::throw_exception.

One thread [1] (dated from May 2008) mentions the error of using
throw_exception to throw non-class types and class types which do not
inherit from std::exception; that specific requirement was not explicitly
documented prior to the Exception update of throw_exception and only
implicitly documented based on the code and the signature of the
user-defined hook. It seems like this root cause of the original problem
was identified fairly quickly. A fix to Serialization was or would have
been fairly trivial, but I guess introduced or would have introduced a
minor backward-compatibility issue...?

A second thread [2] (dated August 2008) started by Robert mentions "issues
with the serialization library" which prompted him to "investigate
boost/throw_exception.hpp", but...I couldn't find any reference to said
issues :(

> Or were those libraries authors who reimplemented the
> > original functionality simply concerned with the overhead introduced
> > by boost::throw_exception?
>
> Here's the real situation. One invests a HUGE amount of effort
> that it takes to get a libary over the various boost hurdles. I don't
> think
> very many people have any idea what it takes to get something
> like file_system, serialization, or others into boost. After this
> huge initial effort you've got to spend some time cleaning up some
> detail and handling user complaints, upgrading documentation etc.
> (don't even mention the time it takes to deal with boost tools).
> So now you can sort of relax as things settle down, you've responded
> to all the questions by upgrading your documentation, etc. etc.
> Of course by the time this happens, you're way behind on your
> "real" work and trying to catch up with that.
>

Understood!

Then you get a problem. OK well you made the library, you better
> fix it. After a fair amount of sleuthing, you track it down to a
> gratuitous
> change to some other library whose behavior has changed without
> you noticing.


I presume "some other library" == boost::throw_exception? AFACT, any
behavioral changes to throw_exception were *intended* to be fully backward
compatible. So I would think that any *breaking* changes as you describe
should (or should have been) filed as a bug against boost::throw_exception.

This is incredibly disheartening. You've invested huge
> amount of effort to get something of this scale "over the hump" and
> now you've been undermined by someone who really isn't being
> considerate and/or doesn't know the implications of what he's doing.
>

Sorry, this sounds is starting to sound like an unfair personal attack
against the individual (Emil) who happened to spearhead the changes to
boost::throw_exception. AFAICT, some of the proposed changes to
boost::throw_exception did not originate with Emil, and ultimately there
was enough consensus from the community to move forward with these proposed
changes (whether this was right or wrong is another issue).

And, if accepted, this would mean a whole new level of effort you have
> to engage in - just to keep things from breaking.
>
> Originally you dealt with this by building a moat around your app/library
> and you only depend on other aps/libraries which you can really trust
> to not let you down. So you do the only thing you really can do. You
> tweak you app so it doesn't depend on the offending component any
> more.


Although I understand your motivations, I still find it a little ironic
that in your endeavor to rid yourself of boost::throw_exception you
introduced a breaking change to Boost.Serialization [3].

In any case, this isn't the only thing you can do. One could work with
community to iron out any issues with your use of boost::throw_exception.

You have to do this be it just takes too much time to really
> investigate the implications of introducing a dependency on a new
> library just to relplace a simple macro. So now your off the hook
> and you can move on with your life - but boost itself is worse off
> because of it since now the code base is more confusing and
> includes replicated functionality which it didn't have before.
>

Yes, I agree, it is worse off.

[...snip back-stabbing...]

And it's even bigger than this. Have you noticed that in many shops
> the ONLY external library they permit is boost? Have you noticed
> that the first place people look for C++ code is boost - even though
> there are at least 100's (maybe 1000's) of C++ code modules
> available at the touch of a buttone. It's two things
>
> a) The review process - which catches most of the situations like this.
> b) Requirement for a test suite and regular execution thereof.
>
> these two things diminish problems like the example here. To me
> this situation is break down in the revew process - which thankfully
> is rare. If situations like this were to occur on a regular basis
> boost wouldn't be nearly as successful as it has been.
>

AFAIK, many Boost-wide decisions are made via consensus among the Boost
community. This appears to me to be such a decision.


> I hope it should be obvious that I don't see posts like:
> "you're wrong - it doesn't take that long to compile (anymore)" or
> "it doesn't have this problem (anymore)" are not really relevant to
> my concerns. They just miss the real point.
>

I don't think they do miss the real point. Backward compatible changes
should be allowed to be introduced into any Boost component, but this
obviously carries a risk that what an author *thinks* is backward
compatible actually breaks something; that's a bug in said component. If
the bug is addressed, everyone's happy, right?

Even if you don't agree, your side of the story would still be more
convincing if you could be more concrete about the actual problems
introduced by the Boost.Exception update of boost::throw_exception.

[...]

> FWIW, I think boost.exception would have had much better reception from
> other authors if the author had
>
> a) implemented as I proposed.
> b) let it "rippen" over a couple of releases.
> c) made a pitch/case to other library authors about what the benefits would
> be if his library were included instead of the traditional way of doing
> things
> d) explained how users would appreciate the "upgrade".
> e) explained how there wouldn't be any downsides.
> f) explained how the library author wouldn't really have to do anything but
> a couple of simple edits.
> g) and accepted the fact that it would take time for people to migrate.
> h) and accepted the fact that in spite of his best efforts, he might not be
> able to convince everyone.
>
> I know it seems like it's a lot easier to just ram it down everyone's
> throat
> while they're
> attention is focused elsewhere. And it likely is - in the short run. But
> hopefully this thread might
> convince the next person considers this strategy that it's not really the
> shortcut it would seem to be.
>

Well I'm not sure duplicating existing functionality is any good either,
especially if it requires double the work from Boost users. At the point at
which you uncovered the issues with boost::throw_exception as they related
to Boost.Serialization, you had already "lost the boost::throw_exception
battle" (based only on my reading of the list archives; perhaps you have a
different recollection of events). As such, I think everyone would have
been better served in the long run by working with Emil and others in
addressing any regressions caused by the boost::throw_exception changes
rather than forking your own Boost.Serialization-local throw_exception,
doubling code and documentation effort, and forcing Boost users to define
and keep track two user-specified functions upon disabling of exceptions.

- Jeff

[1] http://lists.boost.org/Archives/boost/2008/05/136919.php
[2] http://lists.boost.org/Archives/boost/2008/08/141187.php
[3] http://lists.boost.org/Archives/boost/2008/09/142162.php

Nathan Ridge

unread,
Jun 23, 2012, 4:14:12 AM6/23/12
to Boost Developers Mailing List

By the way, my first thought when I encountered this problem
is that C++11 ought to have specified the range-based for loop
in such a way that the lifetime of temporaries in the range
expression is extended for the duration of the loop.

Does anyone share this opinion? Would there be any downsides
to this?

It is also interesting to note that boost::for_each together
with a lambda - a from to which any range-based for loop can
easily be converted - does not suffer from this problem. I think
this corroborates the fact that the range-base for loop is
suboptimally specified in the standard - after all the range-
based for loop was meant to replace things like boost::for_each.

Regards,
Nate

Nathan Ridge

unread,
Jun 23, 2012, 5:13:03 AM6/23/12
to Boost Developers Mailing List

[please ignore that last message, I posted it by accident
to the wrong thread

-Nate]

Fabio Fracassi

unread,
Jun 23, 2012, 5:15:47 AM6/23/12
to bo...@lists.boost.org
On 6/22/12 9:55 PM, Robert Ramey wrote:
> Fabio Fracassi wrote:
>> On 6/22/12 8:58 AM, Robert Ramey wrote:
>>
>>> The problem was the gratuitious inclusion of a new
>>> dependency. The extent/nature of any problem it created or didn't
>>> create is not relevant here.
>>
>> Yes it is, because in reality boost exception solves problems for the
>> users of any library that uses it. When using boost exception I can
>> safely let exceptions escape threads and have them rethrown in the
>> starting thread, for instance.
>
> well, not every application uses threads. Really, I don't think anyone
> can say "solves problems for ANY library which uses it." without
> knowing what the application is.
>

Ok, let me rephrase that, it solves the problem for any application
which have it. Without harming others. More functionality is good! (and
yes I know that more functionality has a cost)


>> It has a real and important reason, because it unifies boost exception
>> handling, nearly for free. The few boost libraries which do not use
>> it, serialization most notably, cause trouble because they need extra
>> care to make exception handling well behaved.
>
> Is there any reason you can't trap any exception from a library
> and rethrow it using boost.exception in your own application?
>

Of course I can, and that's what I end up doing. Its just onerous, and
because I know that there is an easier and cleaner way it feels like a
workaround hack.

As Roger Martin stated in another reply: "I use this heavily and it
works great while simplifying code considerably. Got rid of bubbling
errors and multiple ways to do exceptions/errors. When the unified boost
exceptions came into existence tried them and immediately found a
difference in code style, code size, readability and code maintenance"

Boost Exception allows me to ignore the issue, I don't even have to know
if a peace of code does threading and needs it, it will just work when I
do. These kind of 'Abstraction Enablers' provide real progress for
programming in general, much more than the concrete functionality value
alone.


>>> It makes the library more "fragil".
>>
>> No, it gave your users more functionality in an area of which you were
>> not even aware.
>
> That's exactly what makes it more fragil. From my standpoint, I'm on the
> hook for any problem which occurs in the injected code. Code actually
> have no idea what it does.
>

Thats what I gathered, and what I disagree with. IMVHO This stance you
take does not scale.

>>> It means I have I a new place
>>> to look if something needs looking into. etc.etc.
>>
>> It is a shoulder (not quite a giants, but still) to stand on, which gives
>> you a higher reach!
>
> Gives YOU a higher reach - at my expense.
>
> I will say you've given a rousing endorsement of boost exception
> and a good case for it's merits.
>
> I'm not convinced that you've all the applications of boost libraries
> outside
> your problem domain. If someone wanted to take a serious look at the
> something
> the serialization (or other library) and propose some enhance me - maybe via
> a policy argument or whatever and create a TRAC item, that would be one
> thng. But for one person to inject code/depency into a separate library
> because
> he "knows better what users need" isn't a great idea (unless he wants to
> take
> over maintainence of the library - which of course would be a whole
> different thing.
>

That is how modular development works, you let go of some control in
exchange for synergy effects and free added functionality.
Yes, it creates communication overhead but the win (for the users) is huge.

Mathias Gaunard

unread,
Jun 23, 2012, 5:30:22 AM6/23/12
to bo...@lists.boost.org
On 06/22/2012 02:23 PM, Stewart, Robert wrote:

> In hindsight, I agree with Robert's assertion that there should have been a replacement function, boost::exception::throw_exception() or similar, to introduce the new functionality. Whether the existing function needed to be deprecated is a separate issue. The result is that libraries could knowingly choose the new version, and a dependency on Boost.Exception, or, if warranted, stick with the old.

That would be a terrible idea.

The whole point of the system is that there is a single place where you
enable Boost.Exception support for all libraries.

If some libraries were allowed to stick to non-Boost.Exception-enabled
boost::throw_exception, then you couldn't transfer those exceptions
between threads.

Mathias Gaunard

unread,
Jun 23, 2012, 5:37:10 AM6/23/12
to bo...@lists.boost.org
On 06/22/2012 08:33 PM, Dave Abrahams wrote:

> Good question. We do have two problematic dependency loops in Boost, but
> it's not caused by this sort of header structure:
>
> http://f.cl.ly/items/343N460u3b3039091C0g/deps.pdf
>

What are the loops here? What do the colored boxes and arrows mean?
Also how were those dependencies defined? From analysis of header
includes or just by hand?

Also this doesn't seem to cover all of Boost.

Mathias Gaunard

unread,
Jun 23, 2012, 5:44:58 AM6/23/12
to bo...@lists.boost.org
On 06/22/2012 10:17 PM, Robert Ramey wrote:

> Why does the serialization library have to include code from boost
> exception in order to do this?
>
> You can use boost exception at the same place, catch
> the standard exception that the serialization throws, construct you're
> own boost exception and continue on.

So you're suggesting that people should reimplement the whole API of
Boost.Serialization where each function call is wrapped in a try/catch
with all the expected Boost.Serialization exception types?

Sounds practical. How about Boost.Serialization directly uses a global
togglable mechanism which can be set to use the feature or not instead?


> I
> don't
> see that it would be of any use. here's typical serialization code:

Typical example code is irrelevant. In real life people build complex
systems where several things can happen in different threads and you
need to be able to transfer errors from one thread to the other. You
also write generic code where you cannot predict in advance what the
exact type of the exception you're gonna have is going to be.

Jeffrey Lee Hellrung, Jr.

unread,
Jun 23, 2012, 6:19:56 AM6/23/12
to bo...@lists.boost.org
On Fri, Jun 22, 2012 at 9:37 PM, Jeffrey Lee Hellrung, Jr. <
jeffrey....@gmail.com> wrote:

> I took some time to dig up and read some earlier threads on this. Major
> deja vu here, yo.
>
[...]
Okay, I was wrong in my inference/assumption/assertion that a broad
consensus had been reached regarding the Boost.Exception update of
boost::throw_exception. Another thread [4] I found suggests the issue was
actually not fully discussed prior to the introduction of the
boost::throw_exception updates, seemingly due largely to communication
problems.

Apologies, Robert, regarding this inaccuracy in the previous post; I'm just
trying to research the historical context of this issue :/

[4] http://lists.boost.org/Archives/boost/2008/08/141486.php

- Jeff

Jeffrey Lee Hellrung, Jr.

unread,
Jun 23, 2012, 6:25:02 AM6/23/12
to bo...@lists.boost.org
On Sat, Jun 23, 2012 at 2:30 AM, Mathias Gaunard <
mathias...@ens-lyon.org> wrote:

> On 06/22/2012 02:23 PM, Stewart, Robert wrote:
>
> In hindsight, I agree with Robert's assertion that there should have been
>> a replacement function, boost::exception::throw_**exception() or
>> similar, to introduce the new functionality. Whether the existing function
>> needed to be deprecated is a separate issue. The result is that libraries
>> could knowingly choose the new version, and a dependency on
>> Boost.Exception, or, if warranted, stick with the old.
>>
>
> That would be a terrible idea.
>
> The whole point of the system is that there is a single place where you
> enable Boost.Exception support for all libraries.
>
> If some libraries were allowed to stick to non-Boost.Exception-enabled
> boost::throw_exception, then you couldn't transfer those exceptions between
> threads.
>

Well, clearly, some libraries have been allowed their own throw_exception
implementation for some time, notably Boost.Serialization and
Boost.FileSystem.

>From what I can find in the list archives [1], Boost.FileSystem also had a
similar issue with the requirement that thrown exceptions inherit from
std::exception. However, I'm not sure if [1] prompted the FileSystem-local
hook or if it was resolved in some other way.

- Jeff

[1] http://lists.boost.org/Archives/boost/2008/05/138016.php

Fabio Fracassi

unread,
Jun 23, 2012, 6:39:07 AM6/23/12
to bo...@lists.boost.org
On 6/22/12 10:17 PM, Robert Ramey wrote:

> BUT - now you've sucked me into looking at the merits of including it, I
> don't
> see that it would be of any use. here's typical serialization code:
>
> #include <boost/archiive/binary_iarchive.hpp>
> #include <ifstream>
> ....
> f(...){
> ifsteam is("my file")
> binary_iarchive ia(is);
> try {
> my_data d;
> ia >> d;
> }
> catch(boost::archive::exception ae){
> std::cout << ae.what();
> throw(ae) ; // or throw something else
> }
> return;
> }
>

Well my typical code looks more like

load(...) {
ifstream is("myfile");
binary_iarchive ia(is);
my_data d;
ia >> d;

return;
}

with the first try block "miles" away from the call. With a whole lot of
layers in between. Layers which may or may not invoke threads.

The use you don't see is that I can do this. By not using boost
exception you force me to take extra care either everywhere I use
serialization or everywhere I use threads.
Its not much work, but it still inhibits a much cleaner abstraction level.

regards

Fabio

John Maddock

unread,
Jun 23, 2012, 8:04:08 AM6/23/12
to bo...@lists.boost.org
>>> You've looked into this - did you see any "compelling reason" to
>>> inject this code into the serialization or any other library?
>>
>> Let's try and give some examples:
>
> I really didn't want to get is these specifics. But you've sucked me in.

Huh? I thought that's what you were asking for when you asked for
"compelling reasons".

>> 1) Unlike "regular" exception objects, objects which derive from
>> boost::exception can have additional information added to them either
>> at the call site, or later in the call stack. Consider this case:
>> user opens a std::fstream and passes the object to a serialization
>> method which then throws. Currently you may get some information
>> about the failure, but not the file name because serialization
>> doesn't know what that is (as far as I know). However, with
>> Boost.Exception support, the calling code can annotate the already
>> thrown exception, retaining all the information it contains, but
>> adding whatever extra information (file name for example) is
>> available. See
>> http://www.boost.org/doc/libs/1_49_0/libs/exception/doc/tutorial_transporting_data.html.
>
> Why does the serialization library have to include code from boost
> exception in order to do this?
>
> You can use boost exception at the same place, catch
> the standard exception that the serialization throws, construct you're
> own boost exception and continue on.

No!!!!

Misses the whole point - Boost.Exception allow you to annotate an existing
exception without loosing the original information - and that includes the
*type* of the original exception.

>> 2) As others have already mentioned, Boost.Exception allows arbitrary
>> exception objects to be cloned, amongst other things, this allows
>> exceptions to propagate across threads. For example if a
>> serialization routine is run as a future (quite a reasonable goal),
>> then it would allow exceptions thrown during serialization in the
>> worker thread, to be re-thrown in the calling thread when the result
>> of the future is acquired. See
>> http://www.boost.org/doc/libs/1_49_0/libs/exception/doc/tutorial_exception_ptr.html.
>
> again the same question.

Consider writing a future - in order to preserve all the exception
information, you would have to be able to catch, clone, and then rethrow
*every possible exception type* that may be thrown by the code that the
future calls. It is quite simply impossible.

However, if all thrown exceptions inherit from boost::exception, then you
simply catch that exception type, ask it to clone itself, and rethrow in a
different thread. You preserve all the original error information, and
crucially, all the original type information, even though the future doesn't
itself know what the actual dynamic type of the caught and rethrown
exception is.

This actually looks compelling enough to me, that we should probably mandate
use of BOOST_THROW_EXCEPTION.

>> For me, I've only used (3), but when you need it it's very useful. Both
>> (1) and (2) look like killer use cases to me - not for you - for
>> your users.
>
> Let me be clear. I don't have any complaint about boost exception per se.
>
> My complaint is the process by which it was inject.

Fair enough, but you're still 4 years too late on that one.

I repeat an earlier question - if Boost.Exception were refactored to put the
"core" exception throwing code either into boost/detail/ or indeed directly
into boost/exception.hpp given that there's not much of it, would that
address at least some of your concerns?
Please see my answers above.

Now consider that the serialization code includes some use of
Boost.Filesystem, Boost.Regex (filename parsing) and heaven known whatever
other dependencies the object being [de]serialized depends on (presumably an
object being deserialised could throw any exception Boost is capable of).
If all those exception objects uniformly derive from boost::exception
somewhere in their object hierarchy, then you catch *one* exception type,
annotate it, and rethrow. All the original type information is retained,
clients can catch the boost::exception and enumerate all the information it
holds, or they can catch something more specific like
boost::archive::exception and work from there.

I admit to being new to what boost::exception has to offer, but that looks
pretty compelling to me,

Cheers, John.

Mathias Gaunard

unread,
Jun 23, 2012, 8:57:04 AM6/23/12
to bo...@lists.boost.org
On 06/23/2012 12:25 PM, Jeffrey Lee Hellrung, Jr. wrote:

>> From what I can find in the list archives [1], Boost.FileSystem also had a
> similar issue with the requirement that thrown exceptions inherit from
> std::exception. However, I'm not sure if [1] prompted the FileSystem-local
> hook or if it was resolved in some other way.

All exceptions should inherit from std::exception. There is no need to
involve the boost::exception type in your code to use throw_exception.

John Maddock

unread,
Jun 23, 2012, 10:22:32 AM6/23/12
to bo...@lists.boost.org
>>> From what I can find in the list archives [1], Boost.FileSystem also had
>>> a
>> similar issue with the requirement that thrown exceptions inherit from
>> std::exception. However, I'm not sure if [1] prompted the
>> FileSystem-local
>> hook or if it was resolved in some other way.
>
> All exceptions should inherit from std::exception. There is no need to
> involve the boost::exception type in your code to use throw_exception.

This works both ways - you can and should inherit from std::exception
whether you use BOOST_THROW_EXCEPTION or not, it's just that in the latter
case, they will also inherit from boost::exception (via multiple inheritance
if I understand the machinery correctly).

John.

Brian Wood

unread,
Jun 23, 2012, 11:01:13 AM6/23/12
to bo...@lists.boost.org
Fabio Fracassi:

> That is how modular development works, you let go of some control in
> exchange for synergy effects and free added functionality.
> Yes, it creates communication overhead but the win (for the users) is
huge.
I skipped Boost 1.49 and have been updating these results
using Boost 1.50 --
http://webEbenezer.net/comparison.html<http://webebenezer.net/comparison.html>

. I haven't noticed any performance improvements in the
serialization library that's in Boost from 1.48 to the latest
version.

Shalom,
Brian Wood
Ebenezer Enterprises
http://webEbenezer.net <http://webebenezer.net/>

Brian Wood

unread,
Jun 23, 2012, 1:12:00 PM6/23/12
to bo...@lists.boost.org
John Maddock:

> This actually looks compelling enough to me, that we should probably
mandate
> use of BOOST_THROW_EXCEPTION.

Are you going to take away their library card if an author doesn't
want to do this? ;)


Cheers,

Robert Ramey

unread,
Jun 23, 2012, 3:11:33 PM6/23/12
to bo...@lists.boost.org
John Maddock wrote:
>> Why does the serialization library have to include code from boost
>> exception in order to do this?
>>
>> You can use boost exception at the same place, catch
>> the standard exception that the serialization throws, construct
>> you're own boost exception and continue on.
>
> No!!!!
>
> Misses the whole point - Boost.Exception allow you to annotate an
> existing exception without loosing the original information - and
> that includes the *type* of the original exception.

Here is what I don't get.

When the serialization code was written I
decided that the exception mechanism was that right way to go.
I realized that just a "generic" exeception wouldn't included enough
information so I created boost::archive::exception and extra data
specific the this kind of acception. The file name is
archive_exception.hpp. This exception type has most of the
useful information regarding the exception. Some was excluded
as it would make the type "heavier" than I wanted or would
have required data types which might use the heap or other resources
which of course would be a disaster. It also was carefully designed
not to include RTTI and other stuff which would make the library
less attractive for lighter weight applications. Basically this was
designed as the best balance among all the considerations I had to
take into account - including the desire to pass as much information
as possible to the application.

I also used boost::throw_exception in order to permit the system
to gracefully handle the case where exception were either not
available or not permited in the user environment. boost::throw_exception
was explicilty designed for this purpose and no other.

So - boost::throw_except is changed and.... what? I already included
all the useful information I can add. How can boost::throw_exception
add to this on it's own? What can it possible do that's useful? The
archive_exception is already derived from the standard base class
so it can be caught by catch(std::exception e &). It's derived virtually
from std::exception so the e in can be downcast to the archive_exception
and get all it's data. If the user want's to, he has the option or using
rtti type_id to get the type - but he's not forced to if he want's to
keep his code lean and mean.

To summarize, I don't see how just changing boost::throw_exception
without changing anything else can possible add anything useful to
the library or the users application.

> Consider writing a future - in order to preserve all the exception
> information, you would have to be able to catch, clone, and then
> rethrow *every possible exception type* that may be thrown by the
> code that the future calls. It is quite simply impossible.

> However, if all thrown exceptions inherit from boost::exception, then
> you simply catch that exception type, ask it to clone itself, and
> rethrow in a different thread. You preserve all the original error
> information, and crucially, all the original type information, even
> though the future doesn't itself know what the actual dynamic type of
> the caught and rethrown exception is.

Hmmm - I don't see how just changing the implementation of
boost::throw_exception would change this in anyway. Perhaps you're
suggesting that in addition to chaning the functionality of boost::throw
the serialization libary should redefine archive_exception to derive
from boost::exception rather directly from std::exception. Of course
that's a totally different topic than we've been discussing up until now.
and I guess would be a new thread. But maybe you're not suggesting
that. Sorry if I got this wrong.

Still, you're question obligated me to think a little about this. I would
expect a library such as boost exception would have code along
the following lines somewhere to be included/invoked from user
code.

void * x
x = dynamic_cast<boost::exception be *>(std::current_exception())
if(0 != x){
... // do great boost exception stuff
}
else {
void * x = dynamic_cast<std::exception be *>(std::current_exception());
.. // use what() and do some stuff
}
else{
// handle the case where the library, user didn't bother to use
std::exception
}

But this is totally compatible with the original implementation of
boost::throw_exception!

So it looks to me that changing the functionality of boost::throw adds
nothing
to libraries which don't use boost::exception.

Even if libraries are changed to use THROW_BOOST_EXCEPTION the
only thing added is file # / line # - I havn't heard any users clamoring for
that.

Finally, any users who want real information on the exception will have to
include archive_exception.hpp in any case. True it make users think they are
"handling" something - but if there's not catching archive_exception and
dealing with the specifics, they might as well use std::exception.
So I don't see that boost exception actually adds anything of any value.

> This actually looks compelling enough to me, that we should probably
> mandate use of BOOST_THROW_EXCEPTION.

lol - right.

>> My complaint is the process by which it was inject.
> Fair enough, but you're still 4 years too late on that one.

lol - well I wasn't late when I brought it up the first time. It was right
at release time when this bomb was dropped in at the last moment.

> I repeat an earlier question - if Boost.Exception were refactored to
> put the "core" exception throwing code either into boost/detail/ or
> indeed directly into boost/exception.hpp given that there's not much
> of it, would that address at least some of your concerns?

I don't get this. Wouldn't this still drag in hundreds of lines of code
that aren't being used?
I still don't see how boost exception helps in my example. If you don't care
about handling archive_exception you can just use

ifsteam is("my file")
binary_iarchive ia(is);
my_data d;
ia >> d;

and just handle std::exception upstream. If you really like
boost::exception
your code when you eventually can eventually rethrow

catch (std::exception e){
BOOST_EXCEPTION_THROW_EXCEPTION(e)
}

> Now consider that the serialization code includes some use of
> Boost.Filesystem, Boost.Regex (filename parsing) and heaven known
> whatever other dependencies the object being [de]serialized depends
> on (presumably an object being deserialised could throw any exception
> Boost is capable of). If all those exception objects uniformly derive from
> boost::exception
> somewhere in their object hierarchy, then you catch *one* exception
> type, annotate it, and rethrow. All the original type information is
> retained, clients can catch the boost::exception and enumerate all
> the information it holds, or they can catch something more specific
> like boost::archive::exception and work from there.

How is this different from using std::exception ?

> I admit to being new to what boost::exception has to offer, but that
> looks pretty compelling to me,

Sorry john, I'm still not seeing it. You'll have to dumb it down for
us mortals.

Robert Ramey

Steven Watanabe

unread,
Jun 23, 2012, 3:10:48 PM6/23/12
to bo...@lists.boost.org
AMDG

On 06/23/2012 12:11 PM, Robert Ramey wrote:
>
> I also used boost::throw_exception in order to permit the system
> to gracefully handle the case where exception were either not
> available or not permited in the user environment. boost::throw_exception
> was explicilty designed for this purpose and no other.
>

This is the basic point of contention.

According to those who favor the new version,
boost::throw_exception is a hook to control the
behavior of exceptions thrown by Boost libraries, and
I think this is a perfectly reasonable interpretation.
The original behavior was limited to two options:

a) throw e;
b) User defined boost::throw_exception(std::exception&)

Boost.Exception added a third option:
c) throw enable_current_exception(enable_error_info(x))

The important thing is that adding (c) didn't
change the /interface/ of boost::throw_exception.

> So - boost::throw_except is changed and.... what? I already included
> all the useful information I can add. How can boost::throw_exception
> add to this on it's own?

It can't. Boost.Exception allows /callers/
of your library to add their own information
to the exception if they have more context
than the Serialization library itself does.

>> However, if all thrown exceptions inherit from boost::exception, then
>> you simply catch that exception type, ask it to clone itself, and
>> rethrow in a different thread. You preserve all the original error
>> information, and crucially, all the original type information, even
>> though the future doesn't itself know what the actual dynamic type of
>> the caught and rethrown exception is.
>
> Hmmm - I don't see how just changing the implementation of
> boost::throw_exception would change this in anyway. Perhaps you're
> suggesting that in addition to chaning the functionality of boost::throw
> the serialization libary should redefine archive_exception to derive
> from boost::exception rather directly from std::exception. Of course
> that's a totally different topic than we've been discussing up until now.
> and I guess would be a new thread. But maybe you're not suggesting
> that. Sorry if I got this wrong.
>

Actually, inheriting from boost::exception doesn't
work for this. To enable copying you have to throw
using boost::enable_current_exception.

try {
throw enable_current_exception(x);
} catch(...) {
exception_ptr e = current_exception();
}
// move e to another thread
rethrow_exception(e);

> Still, you're question obligated me to think a little about this. I would
> expect a library such as boost exception would have code along
> the following lines somewhere to be included/invoked from user
> code.
>
> void * x
> x = dynamic_cast<boost::exception be *>(std::current_exception())
> if(0 != x){
> ... // do great boost exception stuff
> }
> else {
> void * x = dynamic_cast<std::exception be *>(std::current_exception());
> .. // use what() and do some stuff
> }
> else{
> // handle the case where the library, user didn't bother to use
> std::exception
> }
>
> But this is totally compatible with the original implementation of
> boost::throw_exception!
>

Sure, but it also has nothing in particular
to do with what Boost.Exception provides.

> So it looks to me that changing the functionality of boost::throw adds
> nothing
> to libraries which don't use boost::exception.
>

You're looking at this the wrong way. It isn't
necessarily the /library/ that uses Boost.Exception
functionality. Whether Boost.Exception is useful
depends on the users of the library. As such,
it seems reasonable to allow users to decide whether
they want to use Boost.Exception, which is exactly
what happens if the library uses the current
incarnation of boost::throw_exception.

> I still don't see how boost exception helps in my example. If you don't care
> about handling archive_exception you can just use
>
> ifsteam is("my file")
> binary_iarchive ia(is);
> my_data d;
> ia >> d;
>
> and just handle std::exception upstream.

The code using Boost.Exception would look like:

typedef boost::error_info<
struct tag_archive_filename, std::string> archive_filename;
...

try {
ifstream is(filename);
binary_archive ia(is);
my_data d;
ia >> d;
} catch (boost::exception& e) {
e << archive_filename(filename);
throw;
}

> If you really like
> boost::exception
> your code when you eventually can eventually rethrow
>
> catch (std::exception e){
> BOOST_EXCEPTION_THROW_EXCEPTION(e)
> }
>

This of course loses the original type of the exception.

>> Now consider that the serialization code includes some use of
>> Boost.Filesystem, Boost.Regex (filename parsing) and heaven known
>> whatever other dependencies the object being [de]serialized depends
>> on (presumably an object being deserialised could throw any exception
>> Boost is capable of). If all those exception objects uniformly derive from
>> boost::exception
>> somewhere in their object hierarchy, then you catch *one* exception
>> type, annotate it, and rethrow. All the original type information is
>> retained, clients can catch the boost::exception and enumerate all
>> the information it holds, or they can catch something more specific
>> like boost::archive::exception and work from there.
>
> How is this different from using std::exception ?
>

std::exception doesn't allow any addition annotation.
Using std::exception, there's simply no way to
add any additional information without either
a) Knowing the type of the original exception, or
b) Discarding all the type information of the original exception.

In Christ,
Steven Watanabe

Kim Barrett

unread,
Jun 23, 2012, 3:30:18 PM6/23/12
to bo...@lists.boost.org
On Jun 23, 2012, at 3:11 PM, Robert Ramey wrote:
> To summarize, I don't see how just changing boost::throw_exception
> without changing anything else can possible add anything useful to
> the library or the users application.
> [...]
> Hmmm - I don't see how just changing the implementation of
> boost::throw_exception would change this in anyway. Perhaps you're
> suggesting that in addition to chaning the functionality of boost::throw
> the serialization libary should redefine archive_exception to derive
> from boost::exception rather directly from std::exception. Of course
> that's a totally different topic than we've been discussing up until now.
> and I guess would be a new thread. But maybe you're not suggesting
> that. Sorry if I got this wrong.

This is incorrect.

boost::throw_exception (in the interesting case, where
BOOST_NO_EXCEPTIONS and BOOST_EXCEPTION_DISABLE are both undefined)
ensures that the thrown object is derived from boost::exception even
if the argument is not. It does this (via enable_error_info(), which
does the heavy lifting) by examining the type E of the argument. If E
is derived from boost::exception, then just use the argument as is.
Otherwise, construct a new object. The class of the new object
derives from both E and boost::exception (multiple inheritance), and
has a conversion constructor for arguments of type E which passes the
argument to the new class's base E object's copy constructor. Apply
that constructor to the original argument, and use the resulting
object. (Note that throw requires the argument to be copy
constructible, so the described mechanism imposes no new constraint on
E by requiring copy construction.)

None of this *requires* any intervention by calling code or library
authors. There is no requirement to explicitly derive from
boost::exception for this to work. A library developer might choose
to derive an exception class from boost::exception, since that will
simplify the resulting generated code and eliminate a copy
construction in invocations of boost::throw_exception, but one gets a
boost::exception based object regardless of what came in.

[Note that boost::exception is *not* derived from std::exception; it is
a "mixin" class that is typically derived from by multiple
inheritance.]

Dave Abrahams

unread,
Jun 23, 2012, 3:42:42 PM6/23/12
to bo...@lists.boost.org

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

> Dave Abrahams wrote:
>> on Fri Jun 22 2012, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
>
>>> Sorry, I just can't understand why anyone fails to see this point.
>>
>> Because, while it's true that it has those effects, that sort of thing
>> happens all the time, and most of us see no reasonable way of stopping
>> it without severely constraining Boost development.
>
>> Don't you regularly "inject new bodies of code" into
>> Boost.Serialization that "replace lines and add no functionality
>> used/needed by" Boost.MPI?
>
> No. I don't do this.

I believe you mean that sincerely, but I just don't see how it's
possible for you to know that. Do you keep track of exactly which of
Boost.Serialization's headers is being used by every dependent Boost
library and make sure that *no* new capabilities creep into any of those
headers as you extend/evolve the library? Even if you _can_ do that for
other Boost libraries, you can't possibly do it for your users.

> I have made some mistakes - particularly in the implementation
> of binary_iarchive which have broken other peoples code. But
> I assure you this was totally unintentional.

Of course it was. Do you think the problems with boost::throw_exception
were intentional?

> This wouldn't mean that no new code is never added. Natually
> one could add a new archive type. But that would only affect
> those who conciously chose to use it.

Yes, if you never touch existing headers, you will never cause such a
situation. But surely you do change existing headers from time-to-time?

> But that would of course that be a different case.
>
>> Don't you expect the author of type_traits to do the same thing?
>
> No. I don't.
>
> If I use something like "is_arithmetic" I expect it's functionality
> to not change in the future.

That's not at all like what you said happened. Sure you would expect
is_arithmetic to remain the same. What you said was that "new bodies of
code" were "injected" that "add no functionality used/needed by
Boost.Serialization." We did that to type_traits when we upgraded it to
work more smoothly with Boost.MPL. Changes like that are rare, but
changes like this one aren't:

The maintainer of is_arithmetic makes changes to support
compiler X. Boost.Serialization does not support compiler X.
Therefore these changes "add no functionality used/needed by
Boost.Serialization."

Such changes might be arbitrarily complicated, including pulling in new
header files.

>> I'm happy to move on if you're really going to put this behind you.
>> If you won't truly be able to, then we should keep talking until we
>> can all understand each other because this is at least the 2nd time
>> we've had a long argument about it and it would be a shame to have to
>> go over the same ground again.
>
> I'm sympathetic to you view here. It wasn't really resolved before -
> we just worked around it. Basically this is what we're going to
> continue to do albeit is a less ad hoc way.

We have a plan that's less ad-hoc than the last one?

> I'm really sympathetic to those who see this as a pointless, endless
> argument.

I'm not among them. I'm just trying to do everything possible to ensure
that this time around the argument is point-ful.

> But obviously it's not for those of us involved in it. For the most
> part I don't doubt the good intentions and sincerity of those who are
> disagreeing with me here. I just think they're wrong and they they
> have failed to make a convincing argument that I'm wrong. And I
> believe that these "wrong ideas" (my view) make a large negative
> impact on software usability and quality.

Some of us are arguing with you because we respect your opinions on
these matters, but aren't able to see the "wrong ideas" you've been
pointing at. Arguing is a way of probing for enlightenment.

My guess so far is that you have something real in mind, but you're not
expressing it with enough precision for others to grasp it. I think it
might help if you could make an effort to be extremely concise, so your
point is in a non-TL;DR context. If you use very few words it should be
very obvious to you whether they'll communicate what you actually mean
to say.

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

Dave Abrahams

unread,
Jun 23, 2012, 3:46:22 PM6/23/12
to bo...@lists.boost.org

on Sat Jun 23 2012, Nathan Ridge <zeratul976-AT-hotmail.com> wrote:

> By the way, my first thought when I encountered this problem
> is that C++11 ought to have specified the range-based for loop
> in such a way that the lifetime of temporaries in the range
> expression is extended for the duration of the loop.
>
> Does anyone share this opinion?

+0. I don't know enough to have an opinion yet.

> Would there be any downsides to this?

Well of course there would. Extending the lifetime of a non-trivial temporary
beyond what's needed creates inefficiencies (memory pressure, register
pressure, worse locality of reference...)

> It is also interesting to note that boost::for_each together
> with a lambda - a from to which any range-based for loop can
> easily be converted - does not suffer from this problem. I think
> this corroborates the fact that the range-base for loop is
> suboptimally specified in the standard - after all the range-
> based for loop was meant to replace things like boost::for_each.

You have a point... though maybe what we really need is
expression-statements ;-)

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


Emil Dotchevski

unread,
Jun 23, 2012, 3:52:47 PM6/23/12
to bo...@lists.boost.org
On Sat, Jun 23, 2012 at 5:57 AM, Mathias Gaunard <
mathias...@ens-lyon.org> wrote:

> On 06/23/2012 12:25 PM, Jeffrey Lee Hellrung, Jr. wrote:
>
> From what I can find in the list archives [1], Boost.FileSystem also had a
>>>
>> similar issue with the requirement that thrown exceptions inherit from
>> std::exception. However, I'm not sure if [1] prompted the FileSystem-local
>> hook or if it was resolved in some other way.
>>
>
> All exceptions should inherit from std::exception. There is no need to
> involve the boost::exception type in your code to use throw_exception.


There were a few examples of libraries emitting exceptions that did not
derive from std::exception in violation of a boost::throw_exception
requirement.

This requirement was not enforced prior to Boost version 1.36. With the
introduction of Boost Exception, we got compile errors in the offending
libraries.

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski

unread,
Jun 23, 2012, 3:58:38 PM6/23/12
to bo...@lists.boost.org
On Sat, Jun 23, 2012 at 7:22 AM, John Maddock <boost...@virgin.net>wrote:

> From what I can find in the list archives [1], Boost.FileSystem also had a
>>>>
>>> similar issue with the requirement that thrown exceptions inherit from
>>> std::exception. However, I'm not sure if [1] prompted the
>>> FileSystem-local
>>> hook or if it was resolved in some other way.
>>>
>>
>> All exceptions should inherit from std::exception. There is no need to
>> involve the boost::exception type in your code to use throw_exception.
>>
>
> This works both ways - you can and should inherit from std::exception
> whether you use BOOST_THROW_EXCEPTION or not, it's just that in the latter
> case, they will also inherit from boost::exception (via multiple
> inheritance if I understand the machinery correctly).
>

Yes, any exception emitted by boost::throw_exception can be intercepted as
std::exception (you get a compile error if you pass a type that doesn't
derive from std::exception), or as boost::exception (it's inserted as a
base type if the passed type doesn't already derive from it).

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Dave Abrahams

unread,
Jun 23, 2012, 4:05:45 PM6/23/12
to bo...@lists.boost.org

on Sat Jun 23 2012, Mathias Gaunard <mathias.gaunard-AT-ens-lyon.org> wrote:

> On 06/22/2012 08:33 PM, Dave Abrahams wrote:
>
>> Good question. We do have two problematic dependency loops in Boost, but
>> it's not caused by this sort of header structure:
>>
>> http://f.cl.ly/items/343N460u3b3039091C0g/deps.pdf
>>
>
> What are the loops here?
> What do the colored boxes and arrows mean?

Each set of same-colored boxes is a SCC in the build dependency graph.
Heavy black arrows are direct dependencies. Dashed arrows are
dependencies introduced by usage-requirements (such as these:
https://github.com/boost-lib/math/blob/master/CMakeLists.txt#L96). The
blue ones are members of a transitive reduction of those usage
dependencies. Ignoring the gray ones *might* make the structure easier
to see.

> Also how were those dependencies defined? From analysis of header
> includes or just by hand?

>From automatically analyzing the CMakeLists.txt files in modularized
Boost
(https://github.com/ryppl/ryppl/blob/develop/scripts/dump_cmake.py).
The entries in the CMakeLists.txt files were generated by automatically
analyzing header files.

> Also this doesn't seem to cover all of Boost.

You don't want to see that graph :-). It looks something like
http://f.cl.ly/items/3V2I3A103K1Y45113s3w/source-deps.pdf

The first one shows only the libraries with build dependencies, i.e. it
eliminates all leaves in the build dependency tree. Since leaves can't
participate in dependency cycles, that reduced view allows us to better
understand the reasons for the SCCs.

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


Dave Abrahams

unread,
Jun 23, 2012, 4:13:49 PM6/23/12
to bo...@lists.boost.org

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

> If you really like boost::exception your code when you eventually can
> eventually rethrow
>
> catch (std::exception e){
> BOOST_EXCEPTION_THROW_EXCEPTION(e)
> }

IIUC, even if you change it to catch by reference, as you should, and
even if std::exception weren't an abstract base class, which it is, that
approach will slice the caught exception and lose all the information
thrown with it. BOOST_EXCEPTION_THROW_EXCEPTION needs to copy the
exception object into this type it builds with multiple inheritance from
boost::exception, and it needs to do this with full knowledge of the
static type of the exception being thrown.

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


It is loading more messages.
0 new messages