throwable .vs. non throwable?

J

Jim Langston

I have a template I use for converting types:

template<typename T, typename F > T StrmConvert( const F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >> to;
return to;
}

template<typename F> std::string StrmConvert( const F from )
{
return StrmConvert<std::string>( from );
}

As you can see, it doesn't throw. If the conversion can not take place,
then it simply returns a default constructed type, which is fine for most
cases I use it. However, there may be a case where I want to throw on error.
I know I could simply copy this template and give it a new name, such as
StrmConvertThrow but I don't like that solution. What I would like to be
able to do (which may not be possible) is something like:

int i = 10;
std::string x;

x = StrmConvert( i ):throwable;

or such. I don't think that's right, well, okay, I know it's not right. I
do know that there is a throw( int ) type keyword for functions. I tried to
duplicate StrmConvert like this:

template<typename T, typename F > T StrmConvert( const F from ) throw(
int )

but got compile time errors.

console5.cpp(17) : warning C4290: C++ exception specification ignored except
to indicate a function is not __declspec(nothrow)
console5.cpp(24) : error C2382: 'StrmConvert' : redefinition; different
exception specifications
console5.cpp(3) : see declaration of 'StrmConvert'

so apparently C++ doesn't distinguish between function signatures by throw
or not. Although I seem to recall something about there being a new, and a
new throwable.

Am I barking up the wrong tree, or is there a way to do what I want?
 
A

Alf P. Steinbach

* Jim Langston:
I have a template I use for converting types:

template<typename T, typename F > T StrmConvert( const F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >> to;
return to;
}

template<typename F> std::string StrmConvert( const F from )
{
return StrmConvert<std::string>( from );
}

As you can see, it doesn't throw. If the conversion can not take place,
then it simply returns a default constructed type, which is fine for most
cases I use it. However, there may be a case where I want to throw on error.
I know I could simply copy this template and give it a new name, such as
StrmConvertThrow but I don't like that solution. What I would like to be
able to do (which may not be possible) is something like:

int i = 10;
std::string x;

x = StrmConvert( i ):throwable;

or such. I don't think that's right, well, okay, I know it's not right. I
do know that there is a throw( int ) type keyword for functions.

That's an exception specification. It specifies which types of
exceptions a function can throw. It doesn't cause exceptions to be thrown.

I tried to
duplicate StrmConvert like this:

template<typename T, typename F > T StrmConvert( const F from ) throw(
int )

but got compile time errors.

console5.cpp(17) : warning C4290: C++ exception specification ignored except
to indicate a function is not __declspec(nothrow)
console5.cpp(24) : error C2382: 'StrmConvert' : redefinition; different
exception specifications
console5.cpp(3) : see declaration of 'StrmConvert'

so apparently C++ doesn't distinguish between function signatures by throw
or not.

You mean, apparently it does distinguish. You forgot to place the same
throw specification on the second overload.

Although I seem to recall something about there being a new, and a
new throwable.

Am I barking up the wrong tree, or is there a way to do what I want?

Uhm, what's wrong with boost::lexical_cast?

But anyway, what you're describing is parameterizing the function with
whether it should throw or not. For that you can check the fail()
member function. If failure and should throw, then throw.

You can pass that parameter as a template parameter (decision at compile
time) or as an ordinary function argument (decision at run time). It
might seem natural to use bool for this. But I advice definining a
suitable enum type, so that the client code becomes more readable --
and that also goes for silly shorthand "Strm": vowels are cheap and
plentiful, there's no need to avoid using them! ;-)

Hope this helps,

- Alf
 
R

Roland Pibinger

I have a template I use for converting types:

template<typename T, typename F > T StrmConvert( const F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >> to;
return to;
}

template<typename F> std::string StrmConvert( const F from )
{
return StrmConvert<std::string>( from );
}

As you can see, it doesn't throw.

Each statement in your code may throw an exception.
If the conversion can not take place,
then it simply returns a default constructed type,

Maybe, maybe not. You cannot forsee this for any type T.
which is fine for most
cases I use it. However, there may be a case where I want to throw on error.
I know I could simply copy this template and give it a new name, such as
StrmConvertThrow but I don't like that solution. What I would like to be
able to do (which may not be possible) is something like:

You misunderstood exception specifications in C++. In general,
templates and exception specifications don't blend.
 
J

James Kanze

I have a template I use for converting types:
template<typename T, typename F > T StrmConvert( const F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >> to;
return to;
}
template<typename F> std::string StrmConvert( const F from )
{
return StrmConvert<std::string>( from );
}
As you can see, it doesn't throw.

I don't see that. On my system, it certainly throws in certain
cases. (If you've not exercised this code enough to see a
bad_alloc exception, then you've not tested it enough.)
If the conversion can not take place,
then it simply returns a default constructed type, which is fine for most
cases I use it. However, there may be a case where I want to throw on error.
I know I could simply copy this template and give it a new name, such as
StrmConvertThrow but I don't like that solution. What I would like to be
able to do (which may not be possible) is something like:
int i = 10;
std::string x;
x = StrmConvert( i ):throwable;

There's no way. Whether a function can throw or not is not
considered in overload resolution, and there's no way for you to
specify that you want a version that doesn't throw, or that
does.

The obvious solution is to make the throwing behavior the
default, and to write something like:

T myT ;
try {
myT = StrmConvert( i ) ;
} catch ( ... ) {
}

in the case where you don't care (which should be extremely rare
in most applications).
I don't think that's right, well, okay, I know it's not right. I
do know that there is a throw( int ) type keyword for functions.

That's an exception specification. The unique example of
programming by contract in the current language---it expresses a
contract, saying that this function will not throw anything
else, and if the function violates the contract, it terminates
the program. (Sort of like assert(), really.)
I tried to duplicate StrmConvert like this:
template<typename T, typename F > T StrmConvert( const F from ) throw(
int )
but got compile time errors.
console5.cpp(17) : warning C4290: C++ exception specification ignored except
to indicate a function is not __declspec(nothrow)
console5.cpp(24) : error C2382: 'StrmConvert' : redefinition; different
exception specifications
console5.cpp(3) : see declaration of 'StrmConvert'
so apparently C++ doesn't distinguish between function
signatures by throw or not.

The exception specification is not part of the function
signature. No more than an assert in the body would be.
Although I seem to recall something about there being a new,
and a new throwable.

That's a completely different issue. Normally, new notifies the
lack of memory by throwing std::bad_alloc. If the user wants to
get a null pointer instead, he can use a placement new with a
no_throw additional parameter, and new will return null, rather
than throwing, if there is not enough memory.
Am I barking up the wrong tree, or is there a way to do what I
want?

My immediate reaction would be to avoid this sort of function to
begin with.
 
J

Jerry Coffin

[email protected] says... said:
You misunderstood exception specifications in C++. In general,
templates and exception specifications don't blend.

Exception specifictions don't blend with coding in general, even without
templates. My advice, at least, is to not use exception specifications
at all, ever.

A few people point out that (at least in theory) an empty exception
specification can allow better optimization of some code under some
circumstances. IMO, this isn't sufficient to justify their use, but
there are some who consider this sufficient justification for using
empty exception specifications.

I don't know of anybody who recommends any other use of exception
specifications at all.
 
R

Roland Pibinger

Exception specifictions don't blend with coding in general, even without
templates. My advice, at least, is to not use exception specifications
at all, ever.

Some people propagated this point of view in the past (the
Stroustrup-had-a-bad-day theory). Actually, exception specifications
are not more broken than any other feature of the C++ language. They
just don't work as in Java. It's neither necessary nor advisable to
define exception specifications for each function. But being able to
specify exception guarantees in code (and not merely in the
documentation) definitely is an advantage.
 
J

Jerry Coffin

Some people propagated this point of view in the past (the
Stroustrup-had-a-bad-day theory).

I haven't (and don't) particularly blame Bjarne for them -- I'm not at
all sure he single-handedly added them, or anything like it.
Actually, exception specifications
are not more broken than any other feature of the C++ language.

If you take "broken" to mean "doesn't/can't work as specified", then I'd
agree -- quite a few compilers implement them as the standard requires.

If you take "broken" to mean "they aren't useful", then I have to
disagree -- I believe that every program that includes even a single
exception specification can be written better without it. In most
(though perhaps not quite all) cases, the only change necessary for this
improvement is to delete the text of the exception specification itself.
They just don't work as in Java.

Irrelevant -- Java's exception specifications are no better.
It's neither necessary nor advisable to define exception specifications
for each function.

....or _any_ function.
But being able to
specify exception guarantees in code (and not merely in the
documentation) definitely is an advantage.

How? When? Please show us a real example. I was strongly in favor of
exception specifications until I really tried to use them. I even used
them sometimes for a while -- but I've yet to see a single situation
where they really accomplish anything useful. Quite the contrary, they
normally abort the program without any chance at any kind of recovery,
which is pretty much exactly the opposite of what you'd typically want.

Simply making a bald assertion that they're useful doesn't cut it in
this case. Given the results of years of experience with them, any claim
that they're useful needs to be accompanied by a concrete example.
 
J

Jim Langston

That's a completely different issue. Normally, new notifies the
lack of memory by throwing std::bad_alloc. If the user wants to
get a null pointer instead, he can use a placement new with a
no_throw additional parameter, and new will return null, rather
than throwing, if there is not enough memory.

I think I'll take a look at the no_throw additional parameter, and attempt
to add it to StrmConvert. If that's the way placement new does it, then
maybe I should emulate it. Although it's most likely some enum or define,
I'd like to use something relatively standard.
My immediate reaction would be to avoid this sort of function to
begin with.

Well, this code was orignally designed for simple ouput without having to
build stringstream in my mainline.

I've since gone to using it for user input via sockets and there are many
times it is perfectly acceptable to allow default constructed values. In
fact, there hasn't been a case yet where it would cause my program to crash
if it wasn't. I parse out the fields and do any rudementary checking before
I pass them to StrmConvert. It is actually the rare occasion I want to know
if it didn't convert correctly (in fact, there hasn't been a case yet, but
I'm building for the future).

For other code I may work on in the future, I may want it to throw, which is
why I'm looking at the best way to do it.
 
R

Roland Pibinger

[email protected] says...

How? When? Please show us a real example.

class DataBase {
// ...
Connection* getConnection (...) throw (SQLException);
};
I was strongly in favor of
exception specifications until I really tried to use them. I even used
them sometimes for a while -- but I've yet to see a single situation
where they really accomplish anything useful.

They are part of the contract between implementor and user. In this
respect they are very useful.
Quite the contrary, they
normally abort the program without any chance at any kind of recovery,
which is pretty much exactly the opposite of what you'd typically want.

If your program crashes because you declared the wrong exception
specification then it's your fault. BTW, C++ exception specifications
don't work as in Java.
Simply making a bald assertion that they're useful doesn't cut it in
this case. Given the results of years of experience with them, any claim
that they're useful needs to be accompanied by a concrete example.

All decent C++ libraries need them (except maybe templatized low level
stuff).
 
J

James Kanze

[...]
Irrelevant -- Java's exception specifications are no better.

They're actually worse, because you can't specify the most
interesting case.
...or _any_ function.
How? When? Please show us a real example.

If you're trying to write exception safe code, you need some
sort of guarantee that certain functions (swap, for example,
with some common idioms) or operations don't throw. As long as
it's just assigning a pointer, fine. You have the nothrow
guarantee from the language. If it involves calling a function,
however, you need a guarantee from the author of the function.
Using an empty exception specification is a simple way of
documenting this guarantee, and it acts very much like an
assert, which fails if the guarantee is broken.
I was strongly in favor of exception specifications until I
really tried to use them. I even used them sometimes for a
while -- but I've yet to see a single situation where they
really accomplish anything useful. Quite the contrary, they
normally abort the program without any chance at any kind of
recovery, which is pretty much exactly the opposite of what
you'd typically want.

If the contractual guarantee is that the function won't throw X,
then aborting the program if it does sounds very much like what
I'd want. It's what assert does for the (many) other checks I
write.

Most of the time, the only guarantee which interests you with
regards to what won't be thrown is the nothrow guarantee.
(There might be exceptions, but I've never encountered them.)
In theory, at least, it would be nice to have some sort of
guarantee as to what will be thrown: if condition X holds,
exception Y will be thrown. I rather think that this is beyond
the current state of compiler capabilities, so we're left with
documentation and code review.
Simply making a bald assertion that they're useful doesn't cut
it in this case. Given the results of years of experience with
them, any claim that they're useful needs to be accompanied by
a concrete example.

Are assert's useful? I find them to be very useful. The C++
exception specification is a sort of an assert with regards to
what might be thrown. The nothrow contract is very important in
some specific cases, and exception specifications are a means of
asserting it.
 
J

James Kanze

class DataBase {
// ...
Connection* getConnection (...) throw (SQLException);

};

Without more details, that looks more like an example of where
they don't work, and should be avoided. (I'd be very surprised
if a function as complex as getConnection could not throw
anything but SQLException---that it couldn't throw bad_alloc,
for example.) From appearances (admittedly superficial, but all
I've got to go on here), you are trying to guarantee that
getConnection will throw SQLException in case it detects an
error (and can't create the connection). Regretfully, exception
specifications can't and don't guarantee that; all it says (as a
comment) is that the function might throw an SQLException,
under some undetermined conditions (but then again, it might
not). All it really says is that regardless of what happens,
this function guarantees that it will not throw any other type
of exception---generally, not a very useful bit of information.
They are part of the contract between implementor and user. In this
respect they are very useful.

Becareful about interpreting the contract, however. It's a
negative contract: the function will not throw anything not
listed, and not that it will throw what is listed (much less
that it will throw it when it should). Just knowing that
DataBase::getConnection might throw SQLException, under some
unspecified conditions, doesn't tell me enough to be useful for
anything; I still need the documentation concerning the
conditions under which it will throw this exception. And once
you've documented that, the extra exception specification
doesn't add any new information.
 
J

James Kanze

[ ... ]
You misunderstood exception specifications in C++. In general,
templates and exception specifications don't blend.
Exception specifictions don't blend with coding in general,
even without templates. My advice, at least, is to not use
exception specifications at all, ever.
A few people point out that (at least in theory) an empty
exception specification can allow better optimization of some
code under some circumstances. IMO, this isn't sufficient to
justify their use, but there are some who consider this
sufficient justification for using empty exception
specifications.

In addition to my other comments, it just occurs to me that
there is one (admittedly very special) case where they are
almost necessary. If you write a placement operator new
function which returns a null pointer if it cannot fulfill the
request, you must give it an empty exception specification.
Without an empty exception specification, the compiler is free
to assume that the function will never return a null pointer,
and generate code like:

T* tmp = ::eek:perator new( sizeof T ) ;
tmp->constructor() ;

If the operator new function has an empty exception
specification, it is required to generate something like:

T* tmp = ::eek:perator new( sizeof T ) ;
if ( tmp != NULL ) {
tmp->constructor() ;
}

As I said, it's a very special case, but it's one case where you
don't have a choice.
 
J

Jerry Coffin

[ ... ]
In addition to my other comments, it just occurs to me that
there is one (admittedly very special) case where they are
almost necessary. If you write a placement operator new
function which returns a null pointer if it cannot fulfill the
request, you must give it an empty exception specification.
Without an empty exception specification, the compiler is free
to assume that the function will never return a null pointer,
and generate code like:

Okay -- that's an example I can agree with. While obscure, it's real,
and I can see where leaving out the exception specification honestly
causes a problem.
 
J

Jerry Coffin

[email protected] says... said:
class DataBase {
// ...
Connection* getConnection (...) throw (SQLException);
};

This lacks the detail necessary to evaluate it, but on the face of it
looks like precisely the sort of situation I'd have used as an example
of them being harmful.
They are part of the contract between implementor and user. In this
respect they are very useful.

Once again: a bald assertion that they're useful doesn't cut it. You
need to provide a real example -- and by a real example, I mean enough
code that I (or whoever reads it) can analyze the code and the
situation, and be shown how and why the code benefits from the exception
specification. Right now you've basically just taken "ret_type func_name
(args) throw(exception_list)", filled in (most of) the blanks with
essentially random names, and repeated the unsupported assertion that
it's useful.
 
J

Jerry Coffin

[...]
They just don't work as in Java.
Irrelevant -- Java's exception specifications are no better.

They're actually worse, because you can't specify the most
interesting case.

I'll take your word for it -- I've used Java exceptions enough to be
quite certain they're no better. I found them more problematic, but
hadn't used them _quite_ enough to be sure the extra problems were
really their fault rather than mine.

[ ... ]
If you're trying to write exception safe code, you need some
sort of guarantee that certain functions (swap, for example,
with some common idioms) or operations don't throw.

True, but I'm not convinced that exception specifications are a good way
to accomplish that.

[ ... ]
If the contractual guarantee is that the function won't throw X,
then aborting the program if it does sounds very much like what
I'd want. It's what assert does for the (many) other checks I
write.

The difference, at least as I see it, is that assert helps you gather
information about the problem, whereas exception specifications throw
away the information that was available.

assert prints out a little bit of useful information before aborting --
but unexpected() just aborts or throws a bad_exception. bad_exception,
in turn, provides no way to retrieve information about the original
exception to help diagnose the problem.

Even if, for example, bad_exception contained a pointer to the original
exception, the whole mechanism would become far more useful in a hurry.
The problem with that, of course, is that we don't know the type for the
pointer -- even though (nearly?) everybody agrees that exception classes
should be a monolithic hierarchy, C++ doesn't require it, so we don't
know what type that pointer should be. If nothing else, it could be a
void *, so you could at least cast it back to the base of the hierarchy
-- but when unexpected() is called, it doesn't receive (a pointer or
reference to) the original exception object, so we can't even do that
much.

Likewise, if unexpected() could find that the exception was (derived
from) std::exception, it could do something like:
std::cerr << original_exception->what();
to give you at least some clue of what went wrong before aborting your
program.

If these were possible and implemented, I'd agree that exception
specifications would become as useful as assert's. Without something
along that line, however, I'm left wondering how they can be considered
even roughly comparable.
 
R

Roland Pibinger

Without more details, that looks more like an example of where
they don't work, and should be avoided. (I'd be very surprised
if a function as complex as getConnection could not throw
anything but SQLException---that it couldn't throw bad_alloc,
for example.) From appearances (admittedly superficial, but all
I've got to go on here), you are trying to guarantee that
getConnection will throw SQLException in case it detects an
error (and can't create the connection). Regretfully, exception
specifications can't and don't guarantee that; all it says (as a
comment) is that the function might throw an SQLException,
under some undetermined conditions (but then again, it might
not). All it really says is that regardless of what happens,
this function guarantees that it will not throw any other type
of exception---generally, not a very useful bit of information.

The information that one and only one type of exception may be thrown
is useful for me as client/user of the library function (I could e.g.
retry to establish the connection). Admittedly, it cannot be specified
under which circumstances the exception is thrown. Function
declarations can only hint semantics.
Becareful about interpreting the contract, however. It's a
negative contract: the function will not throw anything not
listed, and not that it will throw what is listed (much less
that it will throw it when it should). Just knowing that
DataBase::getConnection might throw SQLException, under some
unspecified conditions, doesn't tell me enough to be useful for
anything; I still need the documentation concerning the
conditions under which it will throw this exception. And once
you've documented that, the extra exception specification
doesn't add any new information.

The function (obviously inspired by JDBC) lacks some documentation
which writes down that the function either returns a (pointer to a)
valid connection or throws an exception of type SQLException.
Exception specifications make the interface narrower (= better) for
the user which is an advantage.
 
M

Marcus Kwok

Roland Pibinger said:
Some people propagated this point of view in the past (the
Stroustrup-had-a-bad-day theory). Actually, exception specifications
are not more broken than any other feature of the C++ language. They
just don't work as in Java. It's neither necessary nor advisable to
define exception specifications for each function. But being able to
specify exception guarantees in code (and not merely in the
documentation) definitely is an advantage.

Here is an interesting article regarding exception specifications:

A Pragmatic Look at Exception Specifications
http://www.gotw.ca/publications/mill22.htm
 
J

James Kanze

[...]
They just don't work as in Java.
Irrelevant -- Java's exception specifications are no better.
They're actually worse, because you can't specify the most
interesting case.
I'll take your word for it -- I've used Java exceptions enough to be
quite certain they're no better. I found them more problematic, but
hadn't used them _quite_ enough to be sure the extra problems were
really their fault rather than mine.

The problem is simple: the only really interesting guarantee is
that a function won't throw at all, and in Java, it's impossible
to write such a function. (How can you guarantee that a
function won't raise VirtualMachineError.)

The problem is really deeper than exception specifications. For
some types of errors (like VirtualMachineError, or
AssertionError), even trying to unwind the stack is dangerous.
You want to stop dead. With prejudice. The problem is that
Java refuses to recognize this.
[ ... ]
If you're trying to write exception safe code, you need some
sort of guarantee that certain functions (swap, for example,
with some common idioms) or operations don't throw.
True, but I'm not convinced that exception specifications are
a good way to accomplish that.
[ ... ]
If the contractual guarantee is that the function won't throw X,
then aborting the program if it does sounds very much like what
I'd want. It's what assert does for the (many) other checks I
write.
The difference, at least as I see it, is that assert helps you gather
information about the problem, whereas exception specifications throw
away the information that was available.
assert prints out a little bit of useful information before aborting --
but unexpected() just aborts or throws a bad_exception. bad_exception,
in turn, provides no way to retrieve information about the original
exception to help diagnose the problem.

unexpected() aborts, period. By default at least. And if I
write "throw()" after the function declaration, I am guaranteed,
no matter what, that no exception will leave the function, ever,
and that the stack will never be unwound accross the function
boundary.

After that, I've got a core dump, which should give me all the
information I need. Exactly like assert. (Note that when my
application programs run, standard error is normally connected
to /dev/null. So any message assert may output is lost. It's
the core dump which has the useful information, however.)
Even if, for example, bad_exception contained a pointer to the original
exception, the whole mechanism would become far more useful in a hurry.
The problem with that, of course, is that we don't know the type for the
pointer -- even though (nearly?) everybody agrees that exception classes
should be a monolithic hierarchy, C++ doesn't require it, so we don't
know what type that pointer should be.

The fact that you can't copy an exception of an unknown type is
a problem in general; it makes it impossible to propagate an
exception accross a join, for example. I think there will be
some evolution concerning this in the next version of the
standard. I'm not particularly worried about bad_exception,
however, because I'll never see it.
If nothing else, it could be a
void *, so you could at least cast it back to the base of the hierarchy
-- but when unexpected() is called, it doesn't receive (a pointer or
reference to) the original exception object, so we can't even do that
much.
Likewise, if unexpected() could find that the exception was (derived
from) std::exception, it could do something like:
std::cerr << original_exception->what();
to give you at least some clue of what went wrong before aborting your
program.
If these were possible and implemented, I'd agree that exception
specifications would become as useful as assert's. Without something
along that line, however, I'm left wondering how they can be considered
even roughly comparable.

An exception specification without bad_exception will not cause
bad_exception to be raised. Since the only really useful
exception specification is an empty one, which doesn't allow
bad_exception, you should never see this exception. terminate()
will be called, and the core dump will point you to the exact
line where the exception was raised, along with giving you ca
stack trace back to the function which thought it wasn't
possible.
 
P

Pete Becker

The fact that you can't copy an exception of an unknown type is
a problem in general; it makes it impossible to propagate an
exception accross a join, for example. I think there will be
some evolution concerning this in the next version of the
standard.

It was voted in at last week's meeting: N2179, "Language Support for
Transporting Exceptions between Threads". While copying exceptions
across a join was the motivating factor, the mechanism does not depend
on the presence of threads. You can save a handle to an exception and
rethrow it later.
 
J

Jerry Coffin

[ ... ]
unexpected() aborts, period. By default at least.

I suppose that depends on what you mean by default -- if the exception
specification in question includes bad_exception, the stock version
(i.e. not as a result of set_unexpected) can/will throw objects of type
bad_exception. Of course, as long as you only write empty exception
specifications, that can't happen...
And if I
write "throw()" after the function declaration, I am guaranteed,
no matter what, that no exception will leave the function, ever,
and that the stack will never be unwound accross the function
boundary.

Quite true.
After that, I've got a core dump, which should give me all the
information I need.

At least you hope so.
Exactly like assert. (Note that when my
application programs run, standard error is normally connected
to /dev/null. So any message assert may output is lost. It's
the core dump which has the useful information, however.)

I, for one, find the information supplied by the assert useful. Yes,
there are times it can be/is discarded, but at least to me there's a big
difference between deciding that it's reasonable to discard information
for your specific application(s), and deciding at the language level
that all such information must be discarded for all possible
applications.

[ ... ]
An exception specification without bad_exception will not cause
bad_exception to be raised. Since the only really useful
exception specification is an empty one, which doesn't allow
bad_exception, you should never see this exception.

I can't agree -- if you're seeing an exception raised that shouldn't be,
I think (a modified version of) bad_exception would be a useful way to
help diagnose the problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top