>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<class std::basic_string<char,struct > >> > std::char_traits<char>,class std::allocator<char> >,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