Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> >> What I meant (though sorry I was probably too blunt about it) was that
> >> it's irrelevant whether you actually observed termination or not,
> >> unless you're intending for lexical_cast to work just on that compiler.
> >
> > That's correct, and I meant nothing else, either.
>
> If you understood all along that the copy ctor of your exception class
> could cause termination when the exception was thrown, I don't
> understand why I went through this long twisty discussion just to have
> you tell me so.

What happened was:

1. You told me it could cause termination.
2. I made a test case, and observed that it didn't cause termination on
construction, and that due to the implementation, no copy was made, so it
didn't test the copying (which may cause termination).
3. You said it was irrelevant that no termination was observed.
4. I said that I hadn't claimed the test proved there would be no
termination, since on that platform, the copying wasn't tested.

As you can see, I agreed with you from the beginning. It just seems that you
thought I claimed that since it didn't terminate, it wouldn't do that on any
platform. I didn't mean that, and it seems this misunderstanding was the
cause of this long discussion.

> > I wouldn't have made this such a big issue had you not claimed the
> > implementation didn't do what was requested, when both that and your
> > suggestion implements the request.
>
> I think there's a stronger argument for type_info being a
> representative of the type, because among other things an
> implementation is allowed to have type_info::name() return the empty
> string for all types.

I don't disagree with that. I merely made the point that my implementation
also fulfilled the request, which it seems you now agree to, as well.

I also think returning the type as type_info is better.


Regards,

Terje

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


Re: [boost] Re: Boost MPL problem

2003-03-22 Thread David Abrahams
"Edward Diener" <[EMAIL PROTECTED]> writes:

> "
> recursive type or function dependency context too complex
>
> A template definition was recursive or exceeded complexity limits. For
> example:
>
> template class Factorial : public Factorial
> {
> public:
> operator int ()
> {
> return Factorial ::operator int () * n;
> }
> };
>
> Factorial<7> facSeven; // error on this line"
>
> In the example above there is no specialization for Factorial<0>, which is
> why it is endlessly recursive. I have no idea what MS really means by
> "function dependency context too complex" except as a way of saying that
> their compiler has some limit regarding template definitions which has been
> overstepped.
>
> I have no idea why "operator AUX_WRAPPER_VALUE_TYPE() const { return
> this->value; }" would cause this, but perhaps it is some other construct.

It could be an instantiation depth issue.  Maybe the OP's code needs
more of our loop unrolling technique to avoid deep instantiations.  I
think that can be controlled by #defining BOOST_MPL_UNROLLING_LIMIT
to some number greater than 4 before mpl files are #included.

HTH,
-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


[boost] Re: Boost MPL problem

2003-03-22 Thread Edward Diener
The help gives:

"
recursive type or function dependency context too complex

A template definition was recursive or exceeded complexity limits. For
example:

template class Factorial : public Factorial
{
public:
operator int ()
{
return Factorial ::operator int () * n;
}
};

Factorial<7> facSeven; // error on this line"

In the example above there is no specialization for Factorial<0>, which is
why it is endlessly recursive. I have no idea what MS really means by
"function dependency context too complex" except as a way of saying that
their compiler has some limit regarding template definitions which has been
overstepped.

I have no idea why "operator AUX_WRAPPER_VALUE_TYPE() const { return
this->value; }" would cause this, but perhaps it is some other construct.
Maybe Mr. Gurtovoy can shed some light.

Jaap Suter wrote:
> Hi,
>
> Since I started using the latest version of the MPL, the one that
> shipped with 1.30.0, I've been getting the following error a lot:
>
> e:\library\boost\boost\mpl\aux_\integral_wrapper.hpp(78) : fatal
> error C1202: recursive type or function dependency context too complex
>
> I'm using MSVC 7.0.
>
> It's really to find out what is causing it, because it only happens in
> really deep and complex compile-time calculations. I wasn't getting
> them before, and Intel and GCC work fine as well.
> I understand this message is probably too vague, but any help or
> advice
> would be greatly appreciated.
>
> Regards,
>
> Jaap Suter
>
>
>
> ___
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost



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


Re: [boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread David Abrahams
Kevlin Henney <[EMAIL PROTECTED]> writes:

> In article <[EMAIL PROTECTED]>, David Abrahams
> <[EMAIL PROTECTED]> writes
>>>
>>> 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. 
>>
>>You don't think I know this?
>
> It is not what you said. What you know and what you say can be two
> different things :^)

What I said was that throwing such an exception can lead directly to
terminate().  I didn't say anything about the initial construction of
the exception.  Your interpretation of what I said and what I actually
said can be two different things.  There really wasn't any need to
"correct" me, was there?

>>Terje throws an exception, which causes copying.  
>
> _May_ cause copying. I am not going to dispute the fact that the code is
> entitled to do so, but it is not a requirement. Simply moderating the
> precision of the language, that's all.

More hair-splitting.  Is this really neccessary?  Aren't we trying to
write portable code here?  



>>> If the effect is the same, it does not matter where the string
>>> is formatted. 
>>
>>The effect is not the same though.
>
> Err, this is also what I said in my post a few sentences later. There
> must be an echo ;-)

I normally reply to posts point-by-point, and I sometimes don't go
back and revise just because someone starts making sense later
on.  Sorry.

This has been exceedingly frustrating.  If you make it difficult for
people to point out mistakes they are likely to keep silent in the
future.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread David Abrahams
Terje Slettebø <[EMAIL PROTECTED]> writes:

>> What I meant (though sorry I was probably too blunt about it) was that
>> it's irrelevant whether you actually observed termination or not,
>> unless you're intending for lexical_cast to work just on that compiler.
>
> That's correct, and I meant nothing else, either.

If you understood all along that the copy ctor of your exception class
could cause termination when the exception was thrown, I don't
understand why I went through this long twisty discussion just to have
you tell me so.  If I caused the twisting, I'm sorry.  I didn't mean
for this to get so complicated.

> No, it doesn't; it stores a reference to an object describing them. My
> version stored a string describing them. I just applied the same
> hair-splitting reasoning that made you categorically state that my
> implementation "didn't do that" (what was quoted as requested). My
> implementation do it just as well as your suggestion, both stores
> information describing the types. One is geared towards user-readable
> information, one is geared towards program-readable information. Agree?
>
> I wouldn't have made this such a big issue had you not claimed the
> implementation didn't do what was requested, when both that and your
> suggestion implements the request.

I think there's a stronger argument for type_info being a
representative of the type, because among other things an
implementation is allowed to have type_info::name() return the empty
string for all types.

However, I'm not going to press this issue any further.  

I was just trying to make a simple point that the copy ctor of an
exception object should not throw exceptions.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


[boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Gennadiy Rozental
> >Sorry to interfere to this fine discussion, but from my standpoint
> >introduction of std::type_info into lexical_cast is a big problem. I
usually
> >compile my program with noRTTI flag effectively making any program using
new
> >lexical cast fail to link..
>
> OK, this is a new twist. Not one that can be addressed out of the box,
> however: there is no config feature test that addresses this since, as
> the config docs state, there is no accommodation for disabling now
> commonly supported C++ features such as RTTI.

"Config feature" has nothing to do with what I was talking about. I may not
want to use RTTI even if compiler suports it (and most does). The issue I
have is that some implementations of RTTI cause significant runtime overhead
even if never used (but compiled with it), that may not be acceptable.

> >Would you want to supply type information you
> >may do it like this:
> >
> >struct bad_lexical_cast {
> >...
> >virtual char const* src() = 0;
> >virtual char const* trg() = 0;
> >};
>
> This would not be a massive improvement since the types would be, once
> again, expressed as text rather than as program entities, ie type_info
> objects.

It would be good enough for me (and may be for many others). I do not like
std::type_info based logic anyway.

> >Now, question remains how user will customize ReflectionPolicy. I see at
> >least 2 ways:
> >1. Add third template parameter to the lexical_cast with default value
> >2. Use global trait (in this case you may return customizable type from
src,
> >trg functions instead of char const*)
>
> Neither of these sounds particularly attractive, I'm afraid, and would
> still require config-level feature support.

No. Macro that could be used only for convinience puposes. If we move
default_reflection in separate header (that will include typeinfo) lexical
cast users will need to include it separately. We could include it directly
in lexical_cast.hpp and guard with macro BOOST_LEXICAL_CAST_USE_RTTI

> >I could not afford to include  into my source and never do. And
I
> >do not think lexical cast should force me.
>
> If you can make a case for introducing a standard config feature test
> for RTTI this may be something we could consider using in lexical_cast.
> Otherwise, apologies for the inconvenience :-(

Even if none of the above looks sound for you I still argue that
lexical_cast *should not force* inclusion of typeinfo. It's not
"inconvinience" - it's showstopper. It's much more important than providing
specific type info. In majority of the cases one knows it anyway.

> Kevlin

Gennadiy.




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


[boost] Boost MPL problem

2003-03-22 Thread Jaap Suter
Hi,

Since I started using the latest version of the MPL, the one that shipped
with 1.30.0, I've been getting the following error a lot:

e:\library\boost\boost\mpl\aux_\integral_wrapper.hpp(78) : fatal error
C1202: recursive type or function dependency context too complex

I'm using MSVC 7.0.

It's really to find out what is causing it, because it only happens in
really deep and complex compile-time calculations. I wasn't getting them
before, and Intel and GCC work fine as well.
I understand this message is probably too vague, but any help or advice
would be greatly appreciated.

Regards,

Jaap Suter



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


[boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Kevlin Henney
In article <[EMAIL PROTECTED]>, Gennadiy Rozental
<[EMAIL PROTECTED]> writes
>
>Sorry to interfere to this fine discussion, but from my standpoint
>introduction of std::type_info into lexical_cast is a big problem. I usually
>compile my program with noRTTI flag effectively making any program using new
>lexical cast fail to link.. 

OK, this is a new twist. Not one that can be addressed out of the box,
however: there is no config feature test that addresses this since, as
the config docs state, there is no accommodation for disabling now
commonly supported C++ features such as RTTI.

>Would you want to supply type information you
>may do it like this:
>
>struct bad_lexical_cast {
>...
>virtual char const* src() = 0;
>virtual char const* trg() = 0;
>};

This would not be a massive improvement since the types would be, once
again, expressed as text rather than as program entities, ie type_info
objects.

>Now, question remains how user will customize ReflectionPolicy. I see at
>least 2 ways:
>1. Add third template parameter to the lexical_cast with default value
>2. Use global trait (in this case you may return customizable type from src,
>trg functions instead of char const*)

Neither of these sounds particularly attractive, I'm afraid, and would
still require config-level feature support.

>I could not afford to include  into my source and never do. And I
>do not think lexical cast should force me.

If you can make a case for introducing a standard config feature test
for RTTI this may be something we could consider using in lexical_cast.
Otherwise, apologies for the inconvenience :-(

Kevlin


  Kevlin Henney   phone:  +44 117 942 2990
  mailto:[EMAIL PROTECTED] mobile: +44 7801 073 508
  http://www.curbralan.comfax:+44 870 052 2289
  Curbralan: Consultancy + Training + Development + Review

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


[boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostly lexical_cast.hpp)

2003-03-22 Thread Kevlin Henney
In article <[EMAIL PROTECTED]>, David Abrahams
<[EMAIL PROTECTED]> writes
>>
>> 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. 
>
>You don't think I know this?

It is not what you said. What you know and what you say can be two
different things :^)

>Terje throws an exception, which causes copying.  

_May_ cause copying. I am not going to dispute the fact that the code is
entitled to do so, but it is not a requirement. Simply moderating the
precision of the language, that's all.

>If the copy throws,
>you go directly to terminate().

Correct.

>> 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.
>
>No, you could run out of memory after initial construction but during
>copying.

Err, this is what I just said.

>> 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.
>
>I have serious doubts that this is the best approach.

Likewise, but my post was even-handedly trying to present the options
and how they related to the design.

>> 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.
>
>A limit for what?

A limit for the minimum length required to be held for the 'what'
string. IIRC, this has come up in discussion a couple of times at WG21
meetings.

>>>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. 
>
>"relatively" is a relative term ;-) I guess if you don't mind reading
>GCC's mangled names then I am forced to agree.

It is not a matter of "mind", it is a matter of ability. Many compilers
produce messages of a similar quality :-> Many programmers deal with it.

>>>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.
>
>Not for exception what() messages when avoidable.

In other words, what I said :-> Design recommendations are contingent
not absolute.

>> If the effect is the same, it does not matter where the string
>> is formatted. 
>
>The effect is not the same though.

Err, this is also what I said in my post a few sentences later. There
must be an echo ;-)

>> 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. 
>
>How can a static string hope to hold arbitrary messages containing a
>variety of type names? 

If you looked at the code you would see what Terje's original intent
was, and why this particular aspect would not have been an issue.

Kevlin


  Kevlin Henney   phone:  +44 117 942 2990
  mailto:[EMAIL PROTECTED] mobile: +44 7801 073 508
  http://www.curbralan.comfax:+44 870 052 2289
  Curbralan: Consultancy + Training + Development + Review

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


[boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Kevlin Henney
In article <[EMAIL PROTECTED]>, David Abrahams
<[EMAIL PROTECTED]> writes
>Kevlin Henney <[EMAIL PROTECTED]> writes:
>
>>>Yes. Since type_info objects can't be copied, one might instead store
>>>pointers or references to them. 
>>
>> Pointers would be better because, for better or for worse (mostly for
>> worse), standard exceptions support assignment as part of their
>> interface.
>
>Why should boost exception classes behave like std:: exception
>classes in this regard?

And why should they not? It is an open question.

It depends on how close in style people want the Boost experience to the
standard library to be. I personally dislike the standard's design of
exception classes, but I am willing to accommodate its style for an open
library if that is what is expected.

Kevlin


  Kevlin Henney   phone:  +44 117 942 2990
  mailto:[EMAIL PROTECTED] mobile: +44 7801 073 508
  http://www.curbralan.comfax:+44 870 052 2289
  Curbralan: Consultancy + Training + Development + Review

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


[boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostly lexical_cast.hpp)

2003-03-22 Thread Kevlin Henney
In article <[EMAIL PROTECTED]>, Terje Slettebø
<[EMAIL PROTECTED]> writes
>
>Regarding the other MSVC 6 warning given in the original report, Gennaro
>Prota has suggested using an explicit "!=", rather than relying on the
>implicit conversion from pointer to bool. This also avoids using a cast,
>instead.

Or one could use "stream << input && true" ;-) However, I think if one
is going to twist the expression of the code to satisfy the misplaced
oversensitivity of VC, it may be better to be more explicit than subtle,
ie "!(stream << input).fail()".

Kevlin


  Kevlin Henney   phone:  +44 117 942 2990
  mailto:[EMAIL PROTECTED] mobile: +44 7801 073 508
  http://www.curbralan.comfax:+44 870 052 2289
  Curbralan: Consultancy + Training + Development + Review

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


[boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostly lexical_cast.hpp)

2003-03-22 Thread Kevlin Henney
In article <[EMAIL PROTECTED]>, Terje Slettebø
<[EMAIL PROTECTED]> writes
>
>Storing a couple of type members is not enough, by itself. How would a
>catch-clause taking e.g. a reference to bad_lexical_cast access them? To
>access the typedefs, you need to know the exact type thrown, which means you
>need to know the types to begin with...

Templated catch clauses, anyone? ;-)

Kevlin


  Kevlin Henney   phone:  +44 117 942 2990
  mailto:[EMAIL PROTECTED] mobile: +44 7801 073 508
  http://www.curbralan.comfax:+44 870 052 2289
  Curbralan: Consultancy + Training + Development + Review

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


[boost] When to use which ETI workaround?

2003-03-22 Thread Andreas Huber
Hi Aleksey,

I've stumbled over ETI again. Browsing through MPL I have found different
ways to circumvent it. In my case the following workaround seems
to be sufficient:

template< class State >
struct get_context_ptr_type
{
  typedef typename State::context_ptr_type type;
};

template<>
struct get_context_ptr_type< int >
{
  typedef int type;
};

I.e. by simply specializing a given metafunction with int. How do you decide
when to use which workaround? Have you established rules or do you simply
work your way through them until one works?

Thanks,

Andreas


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


[boost] Re: Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Gennadiy Rozental
> > There's absolutely no reason I can see to make the exact exception
> > type depend on the types concerned.  Just use a straightforward
> > class, something along the lines of:
> >
> >  struct bad_lexical_cast : std::exception
> >  {
> > bad_lexical_cast(
> >std::type_info const& src, std::type_info const& dst)
> >  : m_src(src), m_dst(dst) {}
> > char const* what() throw() { return "bad_lexical_cast"; }
> >
> > std::type_info const& src() const { return m_src; }
> > std::type_info const& dst() const { return m_dst; }
> >   private:
> > std::type_info const& src;
> > std::type_info const& dst;
> >  };
>
> Right. I see that Kevlin also suggest this approach in a later posting.
The
> original version of the extended exception used static initialization, as
> mentioned, which is why it was templated.
>
> I think this is a good approach.
>
> Regarding the other MSVC 6 warning given in the original report, Gennaro
> Prota has suggested using an explicit "!=", rather than relying on the
> implicit conversion from pointer to bool. This also avoids using a cast,
> instead.
>

> Regards,

> Terje

Sorry to interfere to this fine discussion, but from my standpoint
introduction of std::type_info into lexical_cast is a big problem. I usually
compile my program with noRTTI flag effectively making any program using new
lexical cast fail to link.. Would you want to supply type information you
may do it like this:

struct bad_lexical_cast {
...
virtual char const* src() = 0;
virtual char const* trg() = 0;
};

template
struct no_lexical_conversion : struct bad_lexical_cast
{
virtual char const* src() { return
ReflectionPolicy::type_info() }
virtual char const* trg()  { return
ReflectionPolicy::type_info() }
}

struct default_reflection {
   template
   char const* type_info()
   {
static std::type_info ti = typeid(T);
return ti.name().c_str();
   }
}

Now, question remains how user will customize ReflectionPolicy. I see at
least 2 ways:
1. Add third template parameter to the lexical_cast with default value
2. Use global trait (in this case you may return customizable type from src,
trg functions instead of char const*)

I could not afford to include  into my source and never do. And I
do not think lexical cast should force me.

Regards,

Gennadiy.




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


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> >> >> > As it stands, it prints "Exception - Constructor", as it throws
> >> >> > an exception in the constructor of the Exception exception. If
> >> >> > the throw-statement in the constructor is commented out, it
> >> >> > prints "Exception - Exception", apparently not invoking the copy
> >> >> > constructor when throwing the exception (which it's allowed to).
> >> >>
> >> >> Irrelevant.  A program that invokes undefined behavior may appear to
> >> >> work fine also.
> >
> > I did not state the latter part as a general claim, which is why I said
that
> > eliding the copy is something it's allowed to, but not required to.
Thus,
> > there's no argument to consider "irrelevant".
>
> What I meant (though sorry I was probably too blunt about it) was that
> it's irrelevant whether you actually observed termination or not,
> unless you're intending for lexical_cast to work just on that compiler.

That's correct, and I meant nothing else, either.

> >> > The reason the extended error type was added, was that there has
> >> > been requests on this list for storing the types used in the
> >> > conversion, in the exception, to make it easier to know which
> >> > conversion failed.
> >>
> >> That's a good request, but you didn't do that, did you?
> >
> > Let me rephrase it: IIRC, the request was for storing information about
the
> > types used, not how this was to be done. Thus, whether or not this does
what
> > was requested depends on how to interpret the request.
> >
> > The suggestion to store (pointer/reference to) type_info objects doesn't
> > store the types, either; it stores information about them, this time in
a
> > way easier for the program to use.
> >
> > So, I can just as well say as you say: The suggestion you said you meant
> > (storing references to type_info objects) doesn't do that, either, does
it?
>
> Ugh.  As far as it's possible to store a type at all in C++, yes my
> suggestion does store the types.

No, it doesn't; it stores a reference to an object describing them. My
version stored a string describing them. I just applied the same
hair-splitting reasoning that made you categorically state that my
implementation "didn't do that" (what was quoted as requested). My
implementation do it just as well as your suggestion, both stores
information describing the types. One is geared towards user-readable
information, one is geared towards program-readable information. Agree?

I wouldn't have made this such a big issue had you not claimed the
implementation didn't do what was requested, when both that and your
suggestion implements the request.


Regards,

Terje

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


[boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Gennaro Prota
On Sat, 22 Mar 2003 17:39:06 +, Kevlin Henney
<[EMAIL PROTECTED]> wrote:


>Not necessarily. It would be reasonable to fold up the inheritance
>again, and simply provide a two argument constructor and a concrete
>implementation:
>
>class bad_lexical_cast : public std::bad_cast
>{
>public:
>...
>virtual const char *what() throw()
   ^
Do not forget const here!   ---|

>[...]
>(in case anyone had decided to throw bad_lexical_cast in their own
>code)

Aargh! :-)

Genny.

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


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread David Abrahams
Terje Slettebø <[EMAIL PROTECTED]> writes:

>> >> > As it stands, it prints "Exception - Constructor", as it throws
>> >> > an exception in the constructor of the Exception exception. If
>> >> > the throw-statement in the constructor is commented out, it
>> >> > prints "Exception - Exception", apparently not invoking the copy
>> >> > constructor when throwing the exception (which it's allowed to).
>> >>
>> >> Irrelevant.  A program that invokes undefined behavior may appear to
>> >> work fine also.
>
> I did not state the latter part as a general claim, which is why I said that
> eliding the copy is something it's allowed to, but not required to. Thus,
> there's no argument to consider "irrelevant".

What I meant (though sorry I was probably too blunt about it) was that
it's irrelevant whether you actually observed termination or not,
unless you're intending for lexical_cast to work just on that compiler.

>> Just use a string literal; the compiler has to allocate that as part
>> of the program image.
>
> Sure, that's what the original lexical_cast did. However, if you are to
> include in the string info about the types, storing it as a string literal
> is not enough.

No, but you could store 3 char const*s, using type_info::name() for
two of them.

>> > The reason the extended error type was added, was that there has
>> > been requests on this list for storing the types used in the
>> > conversion, in the exception, to make it easier to know which
>> > conversion failed.
>>
>> That's a good request, but you didn't do that, did you?
>
> Let me rephrase it: IIRC, the request was for storing information about the
> types used, not how this was to be done. Thus, whether or not this does what
> was requested depends on how to interpret the request.
>
> The suggestion to store (pointer/reference to) type_info objects doesn't
> store the types, either; it stores information about them, this time in a
> way easier for the program to use.
>
> So, I can just as well say as you say: The suggestion you said you meant
> (storing references to type_info objects) doesn't do that, either, does it?

Ugh.  As far as it's possible to store a type at all in C++, yes my
suggestion does store the types.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0(mostlylexical_cast.hpp)

2003-03-22 Thread David Abrahams
Kevlin Henney <[EMAIL PROTECTED]> writes:

>>Yes. Since type_info objects can't be copied, one might instead store
>>pointers or references to them. 
>
> Pointers would be better because, for better or for worse (mostly for
> worse), standard exceptions support assignment as part of their
> interface.

Why should boost exception classes behave like std:: exception
classes in this regard?

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


[boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostly lexical_cast.hpp)

2003-03-22 Thread Gennaro Prota
On Sat, 22 Mar 2003 11:42:39 -0500, David Abrahams
<[EMAIL PROTECTED]> wrote:

>Gennaro Prota <[EMAIL PROTECTED]> writes:
>> I'm happy that std::type_info has a private copy constructor. Hadn't
>> it been for that, my suggestion to use just a couple of typedefs would
>> have been routinely rejected :-)
>
>I don't think I understand what you're saying here, exactly.

Nor do I! :-) I missed somehow the context of the discussion, as I was
doing many things simultaneously while also having a look at the list.
Sorry for the nonsense.

Genny.

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


Re: [boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> >>From: "Gennaro Prota" <[EMAIL PROTECTED]>
> >
> >> I'm happy that std::type_info has a private copy constructor. Hadn't
> >> it been for that, my suggestion to use just a couple of typedefs would
> >> have been routinely rejected :-)
> >
> > Storing a couple of type members is not enough, by itself. How would a
> > catch-clause taking e.g. a reference to bad_lexical_cast access them? To
> > access the typedefs, you need to know the exact type thrown, which means
you
> > need to know the types to begin with...
>
> There's absolutely no reason I can see to make the exact exception
> type depend on the types concerned.  Just use a straightforward
> class, something along the lines of:
>
>  struct bad_lexical_cast : std::exception
>  {
> bad_lexical_cast(
>std::type_info const& src, std::type_info const& dst)
>  : m_src(src), m_dst(dst) {}
> char const* what() throw() { return "bad_lexical_cast"; }
>
> std::type_info const& src() const { return m_src; }
> std::type_info const& dst() const { return m_dst; }
>   private:
> std::type_info const& src;
> std::type_info const& dst;
>  };

Right. I see that Kevlin also suggest this approach in a later posting. The
original version of the extended exception used static initialisation, as
mentioned, which is why it was templated.

I think this is a good approach.

Regarding the other MSVC 6 warning given in the original report, Gennaro
Prota has suggested using an explicit "!=", rather than relying on the
implicit conversion from pointer to bool. This also avoids using a cast,
instead.


Regards,

Terje

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


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> >> Terje Slettebø <[EMAIL PROTECTED]> 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.
> >
> > What difference would that make? In the example program, it throws an
> > exception from the exception constructor, effectively simulating an
> > out-of-memory exception.
>
> Replace operator new so that it throws unconditionally *after* the
> exception object is constructed.  If you try this on an implementation
> where the exception object gets copied during unwinding, it will
> terminate().  It's the copy ctor that matters in this case.

The test program also had a throwing copy constructor. However, on Intel C++
7.0, the copy was elided, so the copy didn't get tested.

> >> > As it stands, it prints "Exception - Constructor", as it throws
> >> > an exception in the constructor of the Exception exception. If
> >> > the throw-statement in the constructor is commented out, it
> >> > prints "Exception - Exception", apparently not invoking the copy
> >> > constructor when throwing the exception (which it's allowed to).
> >>
> >> Irrelevant.  A program that invokes undefined behavior may appear to
> >> work fine also.

I did not state the latter part as a general claim, which is why I said that
eliding the copy is something it's allowed to, but not required to. Thus,
there's no argument to consider "irrelevant".

> >> >> 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.
> >
> > Yes, I know that, of course. However, since if you just store a
> > pointer, the string has to be allocated some other way. How would
> > you allocate it?
>
> Just use a string literal; the compiler has to allocate that as part
> of the program image.

Sure, that's what the original lexical_cast did. However, if you are to
include in the string info about the types, storing it as a string literal
is not enough.

> > As Kevlin says in another posting, the "terminate on second
> > exception",
>
> He never used that phrase.  What do you mean?

True. I was referring to "In an insufficient-memory condition the former
will result in a bad_alloc being thrown and in the latter a call to
terminate." In other words, if you throw an exception in the copy
constructor, when an exception has already been thrown, i.e. during stack
unwinding, as you also say in the updated "Error and Exception Handling"
document.

> > which I thought you alluded to in your first reply, and maybe you
> > did, may not apply at the point of construction, since it only
> > applies after the evaluation of the throw-expression. In other
> > words, if the construction fails, you only loose the first
> > exception, and it instead throws the new one.
>
> I am aware of how C++ EH works, really!

I know you are. This was mostly to try to get a common understanding, since
I was a little confused about what you meant, and therefore wrote the above,
explaining what I had meant.

> > The reason the extended error type was added, was that there has
> > been requests on this list for storing the types used in the
> > conversion, in the exception, to make it easier to know which
> > conversion failed.
>
> That's a good request, but you didn't do that, did you?

Let me rephrase it: IIRC, the request was for storing information about the
types used, not how this was to be done. Thus, whether or not this does what
was requested depends on how to interpret the request.

The suggestion to store (pointer/reference to) type_info objects doesn't
store the types, either; it stores information about them, this time in a
way easier for the program to use.

So, I can just as well say as you say: The suggestion you said you meant
(storing references to type_info objects) doesn't do that, either, does it?


Regards,

Terje

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


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0(mostlylexical_cast.hpp)

2003-03-22 Thread Kevlin Henney
In message <[EMAIL PROTECTED]>, Terje Slettebø
<[EMAIL PROTECTED]> writes
>>From: "Kevlin Henney" <[EMAIL PROTECTED]>
>
>> However, the decision as to whether this should be in the 'what' string
>> is perhaps one that can be revisited.
>
>Indeed. :)
>
>I wasn't sure what kind of interface to use for this, so I just made it part
>of the what() string.

I am not a great fan of embedding programmer-specific info in exception
text messages as it is unobtainable by the programmer except in a debug
situation -- the correctness of a program should not rely on debugging
:-> -- and such precision is of less use to other users.

>> 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.
>
>Yes. Since type_info objects can't be copied, one might instead store
>pointers or references to them. 

Pointers would be better because, for better or for worse (mostly for
worse), standard exceptions support assignment as part of their
interface.

>This appears to need yet another inheritance
>layer, though, unless the virtual functions for accessing the type_info
>objects are made part of bad_lexical_cast. 

Not necessarily. It would be reasonable to fold up the inheritance
again, and simply provide a two argument constructor and a concrete
implementation:

class bad_lexical_cast : public std::bad_cast
{
public:
bad_lexical_cast()
: source(&typeid(void)), target(&typeid(void))
{
}
bad_lexical_cast(
const std::type_info &source,
const std::type_info &target)
: source(&source), target(&target)
{
}
const std::type_info &source_type() const
{
return *source;
}
const std::type_info &target_type() const
{
return *target;
}
virtual const char *what() throw()
{
return  "bad_lexical_cast: ...";
}
virtual ~bad_lexical_cast() throw()
{
}
private:
const std::type_info *source;
const std::type_info *target;
};

The default constructor would be there for backward compatibility only
(in case anyone had decided to throw bad_lexical_cast in their own
code), but would be deprecated with immediate effect.

>> (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
>> bad_lexical_cast.
>
>I think this is a good solution, and it eliminates any throws from the
>exception. This may also be a more flexible solution, as the type_info
>objects may be used directly, in any custom error message.

Yes, this was my preferred option. My least favourite, which I didn't
list at all, was using an array.

Kevlin


  Kevlin Henney   phone:  +44 117 942 2990
  mailto:[EMAIL PROTECTED] mobile: +44 7801 073 508
  http://www.curbralan.comfax:+44 870 052 2289
  Curbralan: Consultancy + Training + Development + Review

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


Re: [boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread David Abrahams
Terje Slettebø <[EMAIL PROTECTED]> writes:

>>From: "Gennaro Prota" <[EMAIL PROTECTED]>
>
>> On Sat, 22 Mar 2003 09:52:07 -0500, David Abrahams
>> <[EMAIL PROTECTED]> wrote:
>>
>> >Kevlin Henney <[EMAIL PROTECTED]> writes:
>>
>> >> 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.
>> >
>> >Yes, that was my suggestion.
>>
>> I'm happy that std::type_info has a private copy constructor. Hadn't
>> it been for that, my suggestion to use just a couple of typedefs would
>> have been routinely rejected :-)
>
> Storing a couple of type members is not enough, by itself. How would a
> catch-clause taking e.g. a reference to bad_lexical_cast access them? To
> access the typedefs, you need to know the exact type thrown, which means you
> need to know the types to begin with...

There's absolutely no reason I can see to make the exact exception
type depend on the types concerned.  Just use a straightforward
class, something along the lines of:

 struct bad_lexical_cast : std::exception
 {
bad_lexical_cast(
   std::type_info const& src, std::type_info const& dst)
 : m_src(src), m_dst(dst) {}
char const* what() throw() { return "bad_lexical_cast"; }

std::type_info const& src() const { return m_src; }
std::type_info const& dst() const { return m_dst; }
  private:
std::type_info const& src;
std::type_info const& dst;
 };


-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


Re: [boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "Gennaro Prota" <[EMAIL PROTECTED]>

> On Sat, 22 Mar 2003 09:52:07 -0500, David Abrahams
> <[EMAIL PROTECTED]> wrote:
>
> >Kevlin Henney <[EMAIL PROTECTED]> writes:
>
> >> 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.
> >
> >Yes, that was my suggestion.
>
> I'm happy that std::type_info has a private copy constructor. Hadn't
> it been for that, my suggestion to use just a couple of typedefs would
> have been routinely rejected :-)

Storing a couple of type members is not enough, by itself. How would a
catch-clause taking e.g. a reference to bad_lexical_cast access them? To
access the typedefs, you need to know the exact type thrown, which means you
need to know the types to begin with...

I don't understand how this relates to private copy constructor, though,
could you explain?


Regards,

Terje

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


Re: [boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostly lexical_cast.hpp)

2003-03-22 Thread David Abrahams
Gennaro Prota <[EMAIL PROTECTED]> writes:

> On Sat, 22 Mar 2003 09:52:07 -0500, David Abrahams
> <[EMAIL PROTECTED]> wrote:
>
>>Kevlin Henney <[EMAIL PROTECTED]> writes:
>
>>> 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.
>>
>>Yes, that was my suggestion.
>
> I'm happy that std::type_info has a private copy constructor. Hadn't
> it been for that, my suggestion to use just a couple of typedefs would
> have been routinely rejected :-)

I don't think I understand what you're saying here, exactly.
However, I can say this:  exception-handling is a *runtime*
polymorphic mechanism.  Compile-time polymorphism as you can achieve
by carrying type information in nested typedefs is useless in a catch
block.

There's no reason not to store type_info references in the exception
object, though.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread David Abrahams
Terje Slettebø <[EMAIL PROTECTED]> writes:

>> Terje Slettebø <[EMAIL PROTECTED]> writes:
>>
>> >>From: "David Abrahams" <[EMAIL PROTECTED]>
>> >
>> >> Are you saying that you have defined an exception with a std::string
>> >> member?  That's VERY bad!  Throwing that exception can lead directly
>> >> to termination!
>> >
>> > You mean if the exception itself throws during construction or copying?
>>
>> Yes.
>>
>> > 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.
>
> What difference would that make? In the example program, it throws an
> exception from the exception constructor, effectively simulating an
> out-of-memory exception.

Replace operator new so that it throws unconditionally *after* the
exception object is constructed.  If you try this on an implementation
where the exception object gets copied during unwinding, it will
terminate().  It's the copy ctor that matters in this case.

>> > As it stands, it prints "Exception - Constructor", as it throws
>> > an exception in the constructor of the Exception exception. If
>> > the throw-statement in the constructor is commented out, it
>> > prints "Exception - Exception", apparently not invoking the copy
>> > constructor when throwing the exception (which it's allowed to).
>>
>> Irrelevant.  A program that invokes undefined behavior may appear to
>> work fine also.
>
> You said that it may terminate the program. I assumed from that that you
> meant it would call terminate(). 

Yes.  If the copy ctor were called, which as you say it's allowed to.

> Did you instead mean undefined behaviour?  

No.

> If so, how? And how would that be related to terminating the
> program? As you say, anything can happen with undefined behaviour,
> including the "expected" behaviour.

It's related in that there are any number of ways an incorrect program
may appear to work correctly.  I assert that any program throwing
exception objects containing std::string members is incorrect (for
some reasonable definition of "incorrect").

>> >> 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.
>
> Yes, I know that, of course. However, since if you just store a
> pointer, the string has to be allocated some other way. How would
> you allocate it? 

Just use a string literal; the compiler has to allocate that as part
of the program image.

> If you use "new", won't that bring the same potential problem as
> std::string? This is why I thought you might have meant storing an
> array (as STLPort does it), rather than storing a pointer. Storing
> an array eliminates the possibility of throwing an exception at
> construction.

Not exactly, but anyway...
Throwing at construction is problematic, but it's not the big
problem.  The big problem happens when you throw during copying.

>> There's no guarantee you have readable names anyway.  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().
>
> A problem is that what() can't throw, either. So you'd have to wrap it in a
> try-catch. 

Yes, if you insist on trying to format a string there.

> Then there's the issue of what to return from what() if the
> formatting throws.

Yes.  You'd need some fallback strategy.  Big deal; either you
implement the fallback or all your users do.

> As Kevlin says in another posting, the "terminate on second
> exception", 

He never used that phrase.  What do you mean?

> which I thought you alluded to in your first reply, and maybe you
> did, may not apply at the point of construction, since it only
> applies after the evaluation of the throw-expression. In other
> words, if the construction fails, you only loose the first
> exception, and it instead throws the new one.

I am aware of how C++ EH works, really!

> As for throwing in the copy constructor, that might be a problem,

Bingo.

> since the "call by value" semantics of throwing an exception may
> mean that it makes a copy of the exception, after the
> throw-expression is evaluated.

Yes.

> The reason the extended error type was added, was that there has
> been requests on this list for storing the types used in the
> conversion, in the exception, to make it easier to know which
> conversion failed. 

That's a good request, but you didn't do that, did you?  Formatting
them into the what() string is a bad idea unless you are very careful.
See http://www.boost.org/more/error_handling.html

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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

Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0(mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "Kevlin Henney" <[EMAIL PROTECTED]>

> In message <[EMAIL PROTECTED]>, David Abrahams
> <[EMAIL PROTECTED]> writes
> >
> >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.

Indeed. :)

I wasn't sure what kind of interface to use for this, so I just made it part
of the what() string.

> 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.

Yes. Since type_info objects can't be copied, one might instead store
pointers or references to them. This appears to need yet another inheritance
layer, though, unless the virtual functions for accessing the type_info
objects are made part of bad_lexical_cast. For example:

// exception used to indicate runtime lexical_cast failure
class bad_lexical_cast : public std::bad_cast
{
public:
virtual const std::type_info &source_type() const throw() = 0;
virtual const std::type_info &target_type() const throw() = 0;

virtual ~bad_lexical_cast() throw()
{
}
};

namespace detail // actual underlying concrete exception type
{
template
class no_lexical_conversion : public bad_lexical_cast
{
public:
virtual const std::type_info &source_type() const throw() {
return typeid(Source); }
virtual const std::type_info &target_type() const throw() {
return typeid(Target); }

virtual ~no_lexical_conversion() throw()
{
}
virtual const char *what() const throw()
{
return "bad lexical cast: "
   "source type value could not be interpreted as
target"
}
};
}

This also addresses the concern of readable type names, and leaves the
what() string as it was.

> 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
> bad_lexical_cast.

I think this is a good solution, and it eliminates any throws from the
exception. This may also be a more flexible solution, as the type_info
objects may be used directly, in any custom error message.

> (3) Play around with C-style memory management and allocate arrays on
> demand, being sure to trap any bad outcome.
> (4) Leave as is.


Regards,

Terje

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


[boost] Re: MSVC++ 6.0 compiler errors with 1.30.0 (mostly lexical_cast.hpp)

2003-03-22 Thread Gennaro Prota
On Sat, 22 Mar 2003 09:52:07 -0500, David Abrahams
<[EMAIL PROTECTED]> wrote:

>Kevlin Henney <[EMAIL PROTECTED]> writes:

>> 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.
>
>Yes, that was my suggestion.

I'm happy that std::type_info has a private copy constructor. Hadn't
it been for that, my suggestion to use just a couple of typedefs would
have been routinely rejected :-)


Genny.

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


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Terje Slettebø
>From: "David Abrahams" <[EMAIL PROTECTED]>

> Terje Slettebø <[EMAIL PROTECTED]> writes:
>
> >>From: "David Abrahams" <[EMAIL PROTECTED]>
> >
> >> Terje Slettebø <[EMAIL PROTECTED]> writes:
> >>
> >> >> C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(74) :
> > warning
> >> > C4512: 'no_lexical_conversion >> > std::char_traits,class std::allocator >,long>' :
assignment
> >> > operator could not be generated
> >> >
> >> > This is due to that it stores a const std::string object, describing
the
> >> > exception
> >>
> >> Are you saying that you have defined an exception with a std::string
> >> member?  That's VERY bad!  Throwing that exception can lead directly
> >> to termination!
> >
> > You mean if the exception itself throws during construction or copying?
>
> Yes.
>
> > 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.

What difference would that make? In the example program, it throws an
exception from the exception constructor, effectively simulating an
out-of-memory exception.

> > As it stands, it prints "Exception - Constructor", as it throws an
exception
> > in the constructor of the Exception exception. If the throw-statement in
the
> > constructor is commented out, it prints "Exception - Exception",
apparently
> > not invoking the copy constructor when throwing the exception (which
it's
> > allowed to).
>
> Irrelevant.  A program that invokes undefined behavior may appear to
> work fine also.

You said that it may terminate the program. I assumed from that that you
meant it would call terminate(). Did you instead mean undefined behaviour?
If so, how? And how would that be related to terminating the program? As you
say, anything can happen with undefined behaviour, including the "expected"
behaviour.

> >> 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.

Yes, I know that, of course. However, since if you just store a pointer, the
string has to be allocated some other way. How would you allocate it? If you
use "new", won't that bring the same potential problem as std::string? This
is why I thought you might have meant storing an array (as STLPort does it),
rather than storing a pointer. Storing an array eliminates the possibility
of throwing an exception at construction.

> > Sure, that's possible, and I see that STLPort do it, and it's
> > probably safer, as you say. It does mean you have to specify the
> > maximum string length in advance, though. As "no_lexical_conversion"
> > what() prints out the source and target types, it may truncate long
> > type names.
>
> There's no guarantee you have readable names anyway.  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().

A problem is that what() can't throw, either. So you'd have to wrap it in a
try-catch. Then there's the issue of what to return from what() if the
formatting throws.

As Kevlin says in another posting, the "terminate on second exception",
which I thought you alluded to in your first reply, and maybe you did, may
not apply at the point of construction, since it only applies after the
evaluation of the throw-expression. In other words, if the construction
fails, you only loose the first exception, and it instead throws the new
one.

As for throwing in the copy constructor, that might be a problem, since the
"call by value" semantics of throwing an exception may mean that it makes a
copy of the exception, after the throw-expression is evaluated.

The reason the extended error type was added, was that there has been
requests on this list for storing the types used in the conversion, in the
exception, to make it easier to know which conversion failed. It has also
proved useful in the regression testing. bad_lexical_cast was not modified,
to not break the interface, so this type inherits from it.


Regards,

Terje

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


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread David Abrahams
Kevlin Henney <[EMAIL PROTECTED]> writes:

> In message <[EMAIL PROTECTED]>, David Abrahams
> <[EMAIL PROTECTED]> 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. 

You don't think I know this?

Terje throws an exception, which causes copying.  If the copy throws,
you go directly to terminate().

> 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.

No, you could run out of memory after initial construction but during
copying.

> 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.

I have serious doubts that this is the best approach.

 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.

A limit for what?

>>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. 

"relatively" is a relative term ;-) I guess if you don't mind reading
GCC's mangled names then I am forced to agree.

> 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.

That shouldn't be formatted at the throw point.

> 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.

Yes, that was my suggestion.

>>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.

Not for exception what() messages when avoidable.

> If the effect is the same, it does not matter where the string
> is formatted. 

The effect is not the same though.

> 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. 

How can a static string hope to hold arbitrary messages containing a
variety of type names? Or were you not planning to allow lexical cast
to be used in multithreaded programs?  And given that you have to
format a different message each time the exception is thrown I don't
see how you can format the string *before* the constructor runs
without user-intervention!  And even if you do, your code may end up
throwing bad_alloc when the intention was just to throw
bad_lexical_cast, and that can have undesirable consequences for
users.

> The changes required to make the code work under VC have
> made the invisible visible, so the effect is not identical in all
> scenarios.
>
> 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.

-1

> (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
> bad_lexical_cast.

+1

I note that this solution provides a lot more flexibility for someone
who wants to report the error, since

Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread David Abrahams
David Abrahams <[EMAIL PROTECTED]> writes:

> Damn, maybe I need to update more/error_handling.html 

Done.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread Kevlin Henney
In message <[EMAIL PROTECTED]>, David Abrahams
<[EMAIL PROTECTED]> 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
scenarios.

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
bad_lexical_cast.
(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


  Kevlin Henney   phone:  +44 117 942 2990
  mailto:[EMAIL PROTECTED] mobile: +44 7801 073 508
  http://www.curbralan.comfax:+44 870 052 2289
  Curbralan: Consultancy + Training + Development + Review

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


Re: [boost] Problem with KAI C++ and boost::type_traits

2003-03-22 Thread David Abrahams
David Abrahams <[EMAIL PROTECTED]> writes:

> "John Maddock" <[EMAIL PROTECTED]> writes:
>
>>> And furthermore, the code inside #if !BOOST_WORKAROUND(...) is all
>>> NON-workaround code, so the workaround _is_ being used for all
>>> versions 238 and lower.
>>
>> Yes but he's using version 243, which will *not* be using the workaround.
>
> Oh, I misread the number.
>
>>> So I think you're going to have to analyze the problem and the fix
>>> again.
>>
>> We need to change to:
>>
>>  && !BOOST_WORKAROUND(__EDG_VERSION__, <= 243)
>
> OK.  Please go ahead, John.

Nevermind, I did it.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


Re: [boost] Problem with KAI C++ and boost::type_traits

2003-03-22 Thread David Abrahams
"John Maddock" <[EMAIL PROTECTED]> writes:

>> And furthermore, the code inside #if !BOOST_WORKAROUND(...) is all
>> NON-workaround code, so the workaround _is_ being used for all
>> versions 238 and lower.
>
> Yes but he's using version 243, which will *not* be using the workaround.

Oh, I misread the number.

>> So I think you're going to have to analyze the problem and the fix
>> again.
>
> We need to change to:
>
>  && !BOOST_WORKAROUND(__EDG_VERSION__, <= 243)

OK.  Please go ahead, John.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


Re: [boost] MSVC++ 6.0 compiler errors with 1.30.0 (mostlylexical_cast.hpp)

2003-03-22 Thread David Abrahams
Terje Slettebø <[EMAIL PROTECTED]> writes:

>>From: "David Abrahams" <[EMAIL PROTECTED]>
>
>> Terje Slettebø <[EMAIL PROTECTED]> writes:
>>
>> >> C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(74) :
> warning
>> > C4512: 'no_lexical_conversion> > std::char_traits,class std::allocator >,long>' : assignment
>> > operator could not be generated
>> >
>> > This is due to that it stores a const std::string object, describing the
>> > exception
>>
>> Are you saying that you have defined an exception with a std::string
>> member?  That's VERY bad!  Throwing that exception can lead directly
>> to termination!
>
> You mean if the exception itself throws during construction or copying?

Yes.

> 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.


> As it stands, it prints "Exception - Constructor", as it throws an exception
> in the constructor of the Exception exception. If the throw-statement in the
> constructor is commented out, it prints "Exception - Exception", apparently
> not invoking the copy constructor when throwing the exception (which it's
> allowed to).

Irrelevant.  A program that invokes undefined behavior may appear to
work fine also.

>> 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.

> Sure, that's possible, and I see that STLPort do it, and it's
> probably safer, as you say. It does mean you have to specify the
> maximum string length in advance, though. As "no_lexical_conversion"
> what() prints out the source and target types, it may truncate long
> type names.

There's no guarantee you have readable names anyway.  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().

Damn, maybe I need to update more/error_handling.html 

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


Re: [boost] Problem with KAI C++ and boost::type_traits

2003-03-22 Thread Matthias Troyer
On Friday, March 21, 2003, at 09:05 PM, David Abrahams wrote:
Matthias Troyer <[EMAIL PROTECTED]> writes:
When trying to compile the filesystem library with KAI C++ we
encounter a problem in
boost/type_traits/is_base_and_derived.hpp
Uh, wait...

It seems that the workaround is needed also for KCC, since otherwise
we get the error message
line 126: error:
   expression must have (pointer-to-) function type
   BOOST_STATIC_CONSTANT(bool, value =
Looking at the #if before this I find:

&& !BOOST_WORKAROUND(__EDG_VERSION__, <= 238)  && 0
   ^
Where did this come from?--^
Sorry that was what I added to find the problem originally, and forgot 
to remove when I realized what was going on and sent the e-mail. I 
apologize for the confusion this caused. The real line is:

&& !BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
This is line 29 of boost/type_traits/is_base_and_derived.hpp

And furthermore, the code inside #if !BOOST_WORKAROUND(...) is all
NON-workaround code, so the workaround _is_ being used for all
versions 238 and lower.
The version just after that #if is the one that does not compile with 
KCC 4.0 . I interpreted this in the manner that this non-workaround 
version does not work, and that we need the workaround version after 
the #else . Do I see this incorrectly?

Matthias

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


[boost] Re: 1.30.0 - problem with filesystem lib

2003-03-22 Thread Russell Hind
Alisdair Meredith wrote:
Russell Hind wrote:


I had the same problem with C++Builder 6 when first using the filesystem
library.  The default builds for filesystem are single threaded.  If
your application is multi-threaded, then you need to re-build the
filesystem library with multi-threading (it uses mutexes somewhere (I
think from smart_ptr but can't remember)).


That is certainly a poor default choice for the borland compiler.  The
'typical' borland user will be using the shipped VCL class library, and
this is requires MT builds.  Single-threaded is an exceptional
condition, rather than the norm, on this platform.
If MT builds are not to be global defaults, could we at least patch the
jam files to use multithreading on Borland?
I would like both single and multi-threaded to be built for all 
libraries by default.  But at minimum, would like an easy way to find 
out which libraries are affected my multi-threading.  These are:

signals
filesystem
thread (obviously)
The only library I've used that isn't is

date_time

Not sure on regex, but I think its makefiles build all the possible 
versions so it isn't so much of an issue.

Russell

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


Re: [boost] Re: call_traits::value_type

2003-03-22 Thread John Maddock
> I don't doubt that there is a use for the current implementation.  What
I'm
> saying is that calling it "value_type" is wrong because that term is used
> already in standard C++, and with a different meaning.
> call_traits::value_type should be like iterator_traits::value_type -- a
> non-const, non-reference that can be used to store temporary variables in
> algorithms and whatnot.  I suspect that this is the more common usage
> scenario (<-- blind asseriton), and it is the behavior people would
expect.

It depends, compressed_pair relies on the current behaviour: is you create
compressed_pair then you would want it to store references
wouldn't you?

Using call_traits::type>value_type is not so hard IMO.

John


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


Re: [boost] Problem with KAI C++ and boost::type_traits

2003-03-22 Thread John Maddock
> And furthermore, the code inside #if !BOOST_WORKAROUND(...) is all
> NON-workaround code, so the workaround _is_ being used for all
> versions 238 and lower.

Yes but he's using version 243, which will *not* be using the workaround.
 
> So I think you're going to have to analyze the problem and the fix
> again.

We need to change to:

 && !BOOST_WORKAROUND(__EDG_VERSION__, <= 243)

John

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