Boost logo

Boost :

From: Kevlin Henney (kevlin_at_[hidden])
Date: 2003-03-22 09:30:31

In message <u8yv7tv6e.fsf_at_[hidden]>, David Abrahams
<dave_at_[hidden]> writes
>> I've tried the program below on Intel C++ 7.0 and MSVC 6, and I haven't got
>> it to call terminate(). It may be that it doesn't handle exceptions
>> correctly, though.
>Because you are not running in a low-memory condition.

Not quite: there is a difference between the initial construction and
the copy. In an insufficient-memory condition with a compiler that
creates the exception directly, rather than creating and then copying
it, the exception does not become active until the constructor has
completed. If it does not complete, I believe that there is no cause to
call terminate. MSVC is one such compiler, but BCC is not. In an
insufficient-memory condition the former will result in a bad_alloc
being thrown and in the latter a call to terminate.

Given that the workaround in Terje's code was in response to a VC6
limitation (static data members of templates don't initialise
correctly), it may make sense to conditionally compile the code so that
the current code is used for VC6 and Terje's original is used for more
capable compilers.

>>> What's wrong with char const*?
>> You mean storing the string as a character array?
>No, I mean not storing the string at all (char const* is not an
>array), but storing an array is another option.

Storing an array is not a reasonable option in this particular case,
given what the code is trying to achieve. It is either impractical for
the application if the bound is too low or can cause undefined behaviour
if the bound is too high. In other words, unless (or until) the standard
stipulates a limit it's the wrong design whichever way you look at it
for this situation.

>There's no guarantee you have readable names anyway.

That's a purely theoretical rather than practical consideration. In
practice, I believe that all of the compilers that lexical_cast works
under offer something relatively meaningful. The original version of
lexical_cast simply stated, with a string literal, that the conversion
had failed. There was some user demand for supplementary information,
which Terje's version provided.

However, the decision as to whether this should be in the 'what' string
is perhaps one that can be revisited. It would be feasible to avoid any
allocation issues at all by leaving the human readable string as general
as it was before and adding type_info members that described the source
and target types.

>Finally, you
>should never format exception messages at the throw point. An
>exception whose what() needs to print type names should store the
>typeids and put the formatting logic in what().

On the whole this is generally good advice, but it should not be treated
as an absolute. Both lazy and eager evaluation have their place in
design. If the effect is the same, it does not matter where the string
is formatted. In this case, Terje's original intent was to use a static
member to hold the representation, which would have resulted in
formatting the string before the constructor, which is the critical
point of failure. The changes required to make the code work under VC
have made the invisible visible, so the effect is not identical in all

This leads to a number of possible options:

(1) Use the static solution, as Terje originally intended, and use the
current solution only for VC6.
(2) Rollback the design to something closer to the original, ie a fixed-
string literal message as the result of calling 'what', and provide
supplementary information for handlers that care enough to catch a
(3) Play around with C-style memory management and allocate arrays on
demand, being sure to trap any bad outcome.
(4) Leave as is.


  Kevlin Henney phone: +44 117 942 2990
  mailto:kevlin_at_[hidden] mobile: +44 7801 073 508 fax: +44 870 052 2289
  Curbralan: Consultancy + Training + Development + Review

Boost list run by bdawes at, gregod at, cpdaniel at, john at