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_conversionclass std::basic_stringchar,struct
  std::char_traitschar,class std::allocatorchar ,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] 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 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 she is free to inspect and
massage the type names separately from the rest of the text
message, 

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_conversionclass std::basic_stringchar,struct
   std::char_traitschar,class std::allocatorchar ,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
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/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] 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 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


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


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


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


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

2003-03-21 Thread John Swartzentruber
I downloaded 1.30.0 and tried to build my project. I got a few errors 
that seem to be in boost, primarily in lexical_cast. Also, 
weak_ptr.hpp uses bad_weak_ptr without including 
boost/detail/shared_count.hpp anywhere. I can fix that by
including it in my code.

These are the warnings in lexical_cast.hpp. Because I treat 
warnings as errors, these pretty much keep me from using this
version of boost.


C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(74) : warning C4512: 
'no_lexical_conversionclass std::basic_stringchar,struct 
std::char_traitschar,class std::allocatorchar ,long' : assignment operator could 
not be generated
C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(193) : see 
reference to class template instantiation 'boost::detail::no_lexical_conversionclass 
std::basic_stringchar,struct std::char_traitschar,class std::allocatorchar 
,long' being compiled
N:\Source\FontSetupUI.cpp(232) : see reference to function template 
instantiation 'class std::basic_stringchar,struct std::char_traitschar,class 
std::allocatorchar  __cdecl boost::lexical_cast(long)' being compiled
C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(74) : warning C4512: 
'no_lexical_conversionclass std::basic_stringchar,struct 
std::char_traitschar,class std::allocatorchar ,double' : assignment operator 
could not be generated
C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(193) : see 
reference to class template instantiation 'boost::detail::no_lexical_conversionclass 
std::basic_stringchar,struct std::char_traitschar,class std::allocatorchar 
,double' being compiled
N:\Source\FontSetupUI.cpp(410) : see reference to function template 
instantiation 'class std::basic_stringchar,struct std::char_traitschar,class 
std::allocatorchar  __cdecl boost::lexical_cast(double)' being compiled
C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(74) : warning C4512: 
'no_lexical_conversiondouble,class std::basic_stringchar,struct 
std::char_traitschar,class std::allocatorchar  ' : assignment operator could not 
be generated
C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(193) : see 
reference to class template instantiation 
'boost::detail::no_lexical_conversiondouble,class std::basic_stringchar,struct 
std::char_traitschar,class std::allocatorchar  ' being compiled
N:\Source\FontSetupUI.cpp(500) : see reference to function template 
instantiation 'double __cdecl boost::lexical_cast(class std::basic_stringchar,struct 
std::char_traitschar,class std::allocatorchar )' being compiled
C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(147) : warning C4800: 'void 
*' : forcing value to bool 'true' or 'false' (performance warning)
C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(146) : while 
compiling class-template member function 'bool __thiscall 
boost::detail::lexical_streamclass std::basic_stringchar,struct 
std::char_traitschar,class std::allocatorchar ,long::operator (const long )'
C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(147) : warning C4800: 'void 
*' : forcing value to bool 'true' or 'false' (performance warning)
C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(146) : while 
compiling class-template member function 'bool __thiscall 
boost::detail::lexical_streamclass std::basic_stringchar,struct 
std::char_traitschar,class std::allocatorchar ,double::operator (const double 
)'
C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(147) : warning C4800: 'void 
*' : forcing value to bool 'true' or 'false' (performance warning)
C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(146) : while 
compiling class-template member function 'bool __thiscall 
boost::detail::lexical_streamdouble,class std::basic_stringchar,struct 
std::char_traitschar,class std::allocatorchar  ::operator (const class 
std::basic_stringchar,struct std::char_traitschar,class std::allocatorchar  )'



___
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-21 Thread Peter Dimov
John Swartzentruber wrote:
 I downloaded 1.30.0 and tried to build my project. I got a few errors
 that seem to be in boost, primarily in lexical_cast. Also,
 weak_ptr.hpp uses bad_weak_ptr without including
 boost/detail/shared_count.hpp anywhere. I can fix that by
 including it in my code.

weak_ptr.hpp includes shared_ptr.hpp, which in turn includes
detail/shared_count.hpp.

___
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-21 Thread Terje Slettebø
From: John Swartzentruber [EMAIL PROTECTED]

 I downloaded 1.30.0 and tried to build my project. I got a few errors
 that seem to be in boost, primarily in lexical_cast. Also,
 weak_ptr.hpp uses bad_weak_ptr without including
 boost/detail/shared_count.hpp anywhere. I can fix that by
 including it in my code.

 These are the warnings in lexical_cast.hpp. Because I treat
 warnings as errors, these pretty much keep me from using this
 version of boost.

In the reported output there are two warnings, both level 4 warnings, which
are more or less remarks. That's why they are disabled in the lexical_cast
unit tests. They are:

 C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(74) : warning
C4512: 'no_lexical_conversionclass std::basic_stringchar,struct
std::char_traitschar,class std::allocatorchar ,long' : assignment
operator could not be generated

This is due to that it stores a const std::string object, describing the
exception. no_lexical_cast is the concrete exception type returned, and it
inherits from bad_lexical_cast. The reason it stores a string object,
rather than using a static string member (since the information is the same
for all objects of it), is that MSVC 6 couldn't handle that static
initialisation. Ironic, huh? :)

A simple way to fix this is to make the string object non-const, although
there's really no reason for it to be assigned to, as all objects are the
same.

 C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(147) : warning
C4800: 'void *' : forcing value to bool 'true' or 'false' (performance
warning)
 C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(146) :
while compiling class-template member function 'bool __thiscall

This uses the implicit conversion from pointer to bool, and one could
probably avoid the warning with an explicit cast.

An alternative to the above is:

#pragma warning(disable: 4512 4800)

:)


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-21 Thread David Abrahams
Terje Slettebø [EMAIL PROTECTED] writes:

 C:\Program Files\Boost\boost_1_30_0\boost/lexical_cast.hpp(74) : warning
 C4512: 'no_lexical_conversionclass std::basic_stringchar,struct
 std::char_traitschar,class std::allocatorchar ,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!

What's wrong with char const*?

-- 
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-21 Thread Terje Slettebø
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_conversionclass std::basic_stringchar,struct
  std::char_traitschar,class std::allocatorchar ,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?

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.

#include iostream
#include string
#include stdexcept

class Exception : public std::runtime_error
{
public:
  Exception() : std::runtime_error(Exception)
{ throw std::runtime_error(Construction); }

  Exception(const Exception ) : std::runtime_error(Exception (copied))
{ throw std::runtime_error(Copy); }
};

int main()
{
  try
  {
throw Exception();
  }
  catch(const std::exception e)
  {
std::cout  Exception -   e.what()  '\n';
  }
  catch(...)
  {
std::cout  Unknown exception\n;
  }
}

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

 What's wrong with char const*?

You mean storing the string as a character array? 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.


Regards,

Terje

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