Writing custom exceptions in C++ [closed] - c++

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I am coming from a Ruby and Java background and have recently begun exploring C++.
While my initial attempts at creating custom exceptions by simply subclassing exception class failed with obscure, I found the following example posted on a site:
class Exception : public exception
{
public:
Exception(string m="exception!") : msg(m) {}
~Exception() throw() {}
const char* what() const throw() { return msg.c_str(); }
private:
string msg;
};
My understanding of semantics of C++ is not very mature at the moment, and I would like to have a better understanding of what is going on here.
In the statement const char* what() const throw() what does the part const throw() do, and what kind of programming construct is it?
Also, what is the purpose and intent of throw() in the destructor specification ~Exception() and why do I need to have a destructor specification although I don't need it do something in particular? Shouldn't the destructor inherited from exception be sufficient?

const after a method declares that the method does not mutate the object. (There are exceptions, and generally it's used to mean "does not mutate the object in an externally-visible way.)
The throw() after the method declaration is an exception specification; it's similar to the throws E1, E2 exception specifications that you see in Java. However, in C++, exception specifications are not checked at compilation-time and are generally considered to be mostly useless (they are now deprecated). throw() is the only somewhat useful form, meaning that the function declares that it must not throw an exception (and if it does, it's a logical error, and the program will invoke an unexpected exception handler, by default terminating the program).
The destructor is explicitly declared because if left unspecified, the compiler will generate a destructor that invokes the base class destructor, and the compiler-generated destructor will not use a throw() exception specification (despite the fact that throwing exceptions in destructors is never a good idea).

You are currently dealing with some style things of C++!
So when you want to actually have an exception-object you may use std::exception, which is explained here on cppreference.
But since you could throw and catch everything in C++, you may even define your own exception class or use more basic aspects, e.g.
try {
throw("S0M3, M4YB3 CR1PT1C STR1NG!");
} catch(char const* exceptStr) {
SomeFuncThatDecodesTheString(exceptStr);
}
Your other topics are more a kind of personal style or standard:
An empty destructor like ~FooClass() {} is only there two show "I really do nothing!". Sometimes they might also be useful, when you use a strict system for writing your classes (e.g. First the public space, including the standard ctor at first and the standard dtor as the second function ...) to kind of force you (or some other coder) to write into the existing braces/function and therefore not desroying your holy order :)
You may write a throw() behind classes for insurance to other people, that the class does only throw exceptions of the types stated in the parantheses. Therefore a function void FooFunc() throw(int,char) should only throw ints and chars. And an empty throw() is just to actually say "Hey coder, I do not throw anything!". You will often find this in the C++ standard library, since you are (mostly) only able to look at the prototypes and not the source. BTW the throw(someType(s)) might be a lie. The function may throw any other type or simply nothing! But don't be a liar, when you use this ;)
EDIT:
I wanted to add, that noexcept can (since C++11) also be used to declare an function, not to throw any exception. This is pretty more comprehensible than throw().
LG ntor

throw() in the destructor specification means that the destructor doesn't throw exceptions. Destructors in C++ should not throw exceptions - here is why.
Destructors in C++ are not inherited. If you don't write your own destructor then compiler will automatically generate a destructor for you. That destructor will call destructor of a base class if such class exists.
const specifier in Exception::what() declaration means that this method may be called for constant objects of type Exception. throw() specifier means the same as for the destructor.
You should get a book about C++, those are very basic questions.

Related

Is make_unique in initializer list in copy constructor good purpose to not use noexcept specifier?

I have a hurdle with noexcept specifier next to my copy constructor.
#include <memory>
#include <vector>
class Foo final {
public:
Foo() noexcept = default;
Foo(const Foo& oth) : impl_(std::make_unique<Foo::Impl>()) {} // <---
~Foo() noexcept = default;
private:
class Impl;
std::unique_ptr<Impl> impl_;
};
class Foo::Impl {
...
private:
std::vector<int> some_data;
}
I'm not sure if I should put noexcept next to copy constructor while there is std::make_unique that can throw bad_alloc.
Any help will be apreciated!
The cpp coding guidelines are pretty clear about it in E.12: Use noexcept when exiting a function because of a throw is impossible or unacceptable
So you can use noexcept even if the call of that function/ctor could result in an exception, if that exception would - in your opinion - result in a not handleable state of your application.
Example from the guidelines:
vector<double> munge(const vector<double>& v) noexcept
{
vector<double> v2(v.size());
// ... do something ...
}
The noexcept here states that I am not willing or able to handle the situation where I cannot construct the local vector. That is, I consider memory exhaustion a serious design error (on par with hardware failures) so that I'm willing to crash the program if it happens.
So if a failed construction of Foo can be handled using a try-catch block without serious problems. Then you won't use a noexcept there.
Reflecting on some other answers: I wouldn't use noexcept if a function potentially throws, even if you don't care if your program will terminate if it eventually does. Because it will, if a function declared as noexcept throws.
Declaring your function noexcept holds semantic information for the users of your class, they can depend on this information, which is essentially untrue in your case.
EDIT: I recommend you to read Item 14 of Scott Meyers' Effective Modern C++, it describes well the benefits of using noexcept and when to use it.
I believe that this really depends on the context. If you can reasonably handle that exception (and expect it be thrown), then you shouldn't mark it as noexcept. On the other hand if there is no way for your program to recover from the exception, you might as well mark it as noexcept.
I'd say that the second case true when the object to allocate is rather small (you won't be able to do a lot of exception handling if you can't allocate a single char).
The first one should occur for really big objects (then you could postpone allocation for example). That being said, if you are copying a huge object... Why not move it instead?
Simple answer: Don't declare it noexcept, if you know it may throw and you do not have a really good reason to do so (for instance you want your application to call std::terminate if a copy cannot be made).
Ask yourself what the gain would be. Can the compiler optimize anything when it is noexcept? I do not see many cases where this would be the case (the most common case where I see optimizations is for a move as then the std-library containers can use it - they check if a move operation is noexcept so they can keep their guarantees). The other place where you might use it is when you want to document that a function cannot throw. This is obviosuly not the case here.
On the other hand, you will not be able to recover from a possible exception anymore and your program will terminate.
So in summery, you do not gain anything, but you might lose something.
Also consult the core guidelines:
E.12: Use noexcept when exiting a function because of a throw is impossible or unacceptable
The title of this rule may be a little bit confusing. It says that you should declare a function as noexcept, if
it does not throw or
you don't care in case of an exception. You are willing to crash the program because you can not handle an exception such as std::bad_alloc due to memory exhaustion.
It's not a good idea to throw an exception if you are the direct owner of an object.
By the way, the following special member functions are implicitly noexcept:
Default constructor
Destructor (as far as I know even if you explicitly throw in it)
Move and copy constructor
Move and copy assignment operator
When to use noexcept
"best practices"
Having to think about whether or not I need to append noexcept after every function declaration would greatly reduce programmer productivity (and frankly, would be a pain).
Well then use it when it's obvious that the function will never throw.
When can I realistically expect to observe a performance improvement after using noexcept? [...] Personally, I care about noexcept because of the increased freedom provided to the compiler to safely apply certain kinds of optimizations.
It seems like the biggest optimization gains are from user optimizations, not compiler ones due to the possibility of checking noexcept and overloading on it. Most compilers follow a no-penalty-if-you-don't-throw exception handling method so I doubt it would change much (or anything) on the machine code level of your code, although perhaps reduce the binary size by removing the handling code.
Using noexcept in the big 4 (constructors, assignment, not destructors as they're already noexcept) will likely cause the best improvements as noexcept checks are 'common' in template code such as in std containers. For instance, std::vector won't use your class's move unless it's marked noexcept (or the compiler can deduce it otherwise).

Transitioning to C++11 where destructors are implicitly declared with noexcept

In C++11, a destructor without any exception specification is implicitly declared with noexcept, which is a change from C++03. Therefore, a code which used to throw from destructors in C++03 would still compile fine in C++11, but will crash at runtime once it attempts throwing from such a destructor.
Since there's no compile-time error with such a code, how could it be safely transitioned to C++11, short of declaring all and every existing destructor in the code base as being noexcept(false), which would be really over-verbose and intrusive, or inspecting each and every destructor for being potentially throwing, which would be really time-consuming and error-prone to do, or catching and fixing all the crashes at runtime, which would never guarantee that all such cases are found?
Note that the rules are not actually that brutal. The destructor will only be implicitly noexcept if an implicitly declared destructor would be. Therefore, marking at least one base class or member type as noexcept (false) will poison the noexceptness of the whole hierarchy / aggregate.
#include <type_traits>
struct bad_guy
{
~bad_guy() noexcept(false) { throw -1; }
};
static_assert(!std::is_nothrow_destructible<bad_guy>::value,
"It was declared like that");
struct composing
{
bad_guy member;
};
static_assert(!std::is_nothrow_destructible<composing>::value,
"The implicity declared d'tor is not noexcept if a member's"
" d'tor is not");
struct inheriting : bad_guy
{
~inheriting() { }
};
static_assert(!std::is_nothrow_destructible<inheriting>::value,
"The d'tor is not implicitly noexcept if an implicitly"
" declared d'tor wouldn't be. An implicitly declared d'tor"
" is not noexcept if a base d'tor is not.");
struct problematic
{
~problematic() { bad_guy {}; }
};
static_assert(std::is_nothrow_destructible<problematic>::value,
"This is the (only) case you'll have to look for.");
Nevertheless, I agree with Chris Beck that you should get rid of your throwing destructors sooner or later. They can also make your C++98 program explode at the most inconvenient times.
As 5gon12eder have mentioned, there are certain rules which result in a destructor without an exception specification to be implicitly declared as either noexcept or noexcept(false). If your destructor may throw and you leave it up to the compiler to decide its exception specification, you would be playing a roulette, because you are relying on the compiler's decision influenced by the ancestors and members of the class, and their ancestors and members recursively, which is too complex to track and is subject to change during the evolution of your code. Therefore, when defining a destructor with a body which may throw, and no exception specification, it must be explicitly declared as noexcept(false). On the other hand, if you are certain that the body may not throw, you may want to declare it noexcept to be more explicit and help the compiler optimize, but be careful if you choose to do this, because if a destructor of any member/ancestor of your class decides to throw, your code will abort at runtime.
Note that any implicitly defined destructors or destructors with empty bodies pose no problems. They are only implicitly noexcept if all destructors of all members and ancestors are noexcept as well.
The best way to proceed with the transition is therefore to find all destructors with non-empty bodies and no exception specifications and declare every one of them which may throw with noexcept(false). Note that you only need to check the body of the destructor - any immediate throws it does or any throws done by the functions it calls, recursively. There's no need to check destructors with empty bodies, destructors with an existing exception specification, or any implicitly defined destructors. In practice, there would not be that many of those left to be checked, as the prevalent use for those is simply freeing resources.
Since I'm answering to myself, that's exactly what I ended up doing in my case and it was not that painful after all.
I went through this same dilemma myself once.
Basically what I concluded is that, accepting the fact that those destructors are throwing and just living with the consequences of that is usually much worse than going through the pain of making them not throw.
The reason is that you risk even more volatile and unpredictable states when you have throwing destructors.
As an example, I worked on a project once where, for various reasons, some of the developers were using exceptions for flow control in some part of the project, and it was working fine for years. Later, someone noticed that in a different part of the project, sometimes the client was failing to send some network messages that it should send, so they made an RAII object which would send the messages in its destructor. Sometimes the networking would throw an exception, so this RAII destructor would throw, but who cares right? It has no memory to clean up so its not a leak.
And this would work fine for 99% of the time, except when the exception flow control path happened to cross the networking, which then also throws an exception. And then, you have two live exceptions being unwound at once, so "bang you're dead", in the immortal words of C++ FAQ.
Honestly I would much rather have the program terminate instantly when a destructor throws, so we can have a talk with who wrote the throwing destructor, than try to maintain a program with intentionally throwing destructors, and that's the consensus of the committee / community it seems. So they made this breaking change to help you assert that your destructors are being good and not throwing. It may be a lot of work if your legacy code base has lots of hacks in it but if you want to keep developing it and maintaining it, at least on C++11 standard, you are likely better off to do the work of cleaning up the destructors.
Bottom Line:
You are right, you can't really hope to guarantee that you find all possible instances of a throwing destructor. So there will probably be some scenarios where when your code compiles at C++11, it will crash in cases that it wouldn't under C++98 standard. But on the whole, cleaning up the destructors and running as C++11 is probably going to be a whole lot more stable than just going with the throwing destructors on old standard.

Does adding `noexcept(false)` benefit the code in any way?

Recently in my code I have been explicitly writing noexcept(false) on functions that I know do throw exceptions, mainly for people reading the code. However, I am wondering if this affects the behavior of my code or the way the compiler interprets it. Does it make any difference?
Note: I am aware that destructors are implicitly noexcept and that you have to specify noexcept(false) to change that, I am wondering about other functions.
Having no exception-specifier and explicitly stating noexcept(false) are equivalent, see §15.4/12:
A function with no exception-specification or with an exception-specification of the form noexcept(constant-expression) where the constant-expression yields false allows all exceptions.
So the compiler should not distinguish between them when considering exceptions.
More importantly, there's no need for you to be tacking on noexcept(false) to your functions. As a C++ developer, you should assume every function throws by default (which is why the standard takes this stance), so you're adding no new information by writing it out; it's a waste of time for everyone.
Rather, do mark the special case where a function definitely does not throw with noexcept, and do mark the cases where a function may throw depending on some condition with noexcept(condition).
If your function is purposefully the source of some exception E, write that in your documentation.
The one case I can think of is on a destructor. I know you should never throw in a destructor. But in some cases you are stuck with code that does this and have no work around.
Since c++ automagically adds noexcept to destructors, this is the only way to undo it and prevent app terminate when the code throws.
https://github.com/chriskohlhoff/asio/issues/1216
from: https://akrzemi1.wordpress.com/2011/09/21/destructors-that-throw/
The compiler will still invisibly add specification noexcept to your
destructor. And this means that the moment your destructor throws an
exception, std::terminate will be called, even if there was no
double-exception situation. If you are really determined to allow your
destructors to throw, you will have to specify this explicitly; you
have three options:
Explicitly specify your destructor as noexcept(false),
Inherit your class from another one that already specifies its destructor as noexcept(false).
Put a non-static data member in your class that already specifies its destructor as noexcept(false).
In his book More Exceptional C++, Herb Sutter has the following snippet (pp. 130):
The right answer to the Example 19-1 is much simpler:
// Example 19-4: The right solution
//
T::~T() /* throw() */
{
// ... code that won't throw ...
}
Example 19-4 demonstrates how to make a design decision instead of waffling.
Note that the throw() throws-nothing exception specification
is only a comment. That's the style I've chosen to follow, in part
because it turns out that exception specifications confer a lot less
benefit than they're worth. Whether or not you decide to actually write the specification is a matter of taste.
(emphasis mine)
So, I feel I must point out that one of the leading experts in C++ exception-safe code seems to be against the whole concept of adding exception specifications for the compiler to use (but still leaving it in the code for the programmers to understand).
Just thought it may be interesting info...

Function exceptions specification and standard exceptions - foo() throw(Exception)

In C++ you may declare function with exception specification like this:
int foo() const throw(Exception);
I found those two links:
http://www.cplusplus.com/doc/tutorial/exceptions/ and
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr156.htm
But several things end up unanswered...
Question 1: why to add exception specification? Will it bring any performance increase? What will be different for compiler? Because it seems just like an information for programmer to me.
Question 2: what will happend (what should happen) if I throw something that isn't in specification? For example:
int foo() throw(int) {
throw char; // Totally unrelated classes, not types in real
}
Question 3: function/method shouldn't throw anything. I found at least two (three, alternative syntax for different compilers) ways to specify no exception throwing:
int foo() throw();
int foo() __attribute(nothrow)__ for gcc
int foo() nothrow for visual C++
Which one is "correct"? Is there any difference? Which one should I use?
Question 4: "standart exceptions", bad_alloc,bad_cast,bad_exception,bad_typeid and ios_base::failure.
Ok bad_alloc is self explaining and I know how (and more importantly when) to use it (add to exception specification), but what about the others? None of them does really ring a bell... Which "code pieces" are they associated with? Like bad_alloc is associated with new char[500000].
Question 5: If I have exception classes hierarchy, like this:
class ExceptionFileType {
virtual const char * getError() const = 0;
};
class ExceptionFileTypeMissing : public ExceptionFileType {
virtual const char *getError() cosnt {
return "Missing file";
}
}
Should I use:
int foo() throw(ExceptionFileType);
Or:
int foo() throw(ExceptionFileTypeMissing,ExceptionFileTypeNotWritable,ExceptionFileTypeNotReadable,...)
Note: answers with references would be great. I'm looking for good practice tips.
The simple "good practice" tip is: don't use exception specifications.
Essentially the only exception to that is the possibility of an empty exception specification: throw(). That's sufficiently useful that in C++11 it's been given its own keyword (noexcept). It's generally agreed that any non-empty exception specification is a lousy idea though.
Exception specifications (other than noexcept) are officially deprecated -- and unlike many deprecated features, removing this would affect little enough source code that I think there's a good chance it really will eventually be removed (certainly no guarantee, but a pretty fair chance anyway).
As for what happens when/if you do throw an exception of a type not allowed by the exception specification: std::unexpected() gets invoked. By default, that invokes terminate(). You can use std::set_unexpected to set your own handler -- but about all you can reasonably do is add some logging before you terminate(). Your unexpected handler is not allowed to return.
Question 1
Don't bother. They were a bad idea, and were deprecated in the latest version of the language. They give no benefit to the compiler, since they are checked at runtime; if anything, they might hurt performance in some cases.
Question 2
A function called std::unexpected will be called. By default, this calls std::terminate; by default, that terminates the program. Both of these behaviours can be changed, using std::set_unexpected and std::set_terminate to install your own handler, if you really want to.
Question 3
throw() was the standard way to do it; the others are non-portable compiler extensions. In C++11, you might use noexcept, which gives a compile-time check that nothing can throw, rather than a run-time check that nothing does throw.
Question 4
bad_cast is thrown when a dynamic_cast of a reference fails.
bad_exception is thrown in some weird circumstances when an exception specification is violated.
bad_typeid is thrown if evaluating the argument to typeid involves dereferencing a null pointer
ios_base::failure is thrown by the input/output library (<iostream> etc.) when some operations fail
Question 5
If you want to allow the entire heirarchy to be thrown, then just specify the base class. But you shouldn't be using exception specifiers at all.
First, let's be very clear what an exception specification does: it's
more or less like an assert that can't be disabled, asserting that you
will not exit the function with an exception other than the ones
missing. As such, it's utility is far more limited than it would seem
at first; for the most part (and in this case, I can't imagine an
exception), the only really useful guarantee is throw(), which
guarantees that no exception will be thrown; if you want to write
exception safe code, you'll need this guarantee for a few low level
functions.
In practice, although throw() could allow some additional compiler
optimizations, the generic implementation tends to result in less
efficient code when an exception specification is used. In C++11, the
throw() has been replaced by noexcept, presumably with the hope that
compiler implementers will do something intelligent with it.
EDIT:
Since everyone (including myself) seems to have missed your question 4:
bad_alloc will be thrown by the operator new function if it cannot
allocate the memory.
bad_cast will be thrown by a dynamic_cast to a reference, in the
case where the cast fails. (A dynamic_cast to a pointer returns a
null pointer in such cases.)
bad_exception will be thrown when an exception specification is
violated, provided the exception specification allows bad_exception.
(In other words, forget it.)
bad_typeid will be thrown if you try to use typeid with a null
pointer.
ios_base::failure will be thrown if you request a stream to throw in
case of errors.
Practically speaking: you'll catch bad_alloc if you want to recover
and continue from out of memory situations. Which means not very often.
(It's very, very difficult to recover from an out of memory situation.)
For bad_cast, it's probably preferrable to use pointers, and test for
null, if you aren't sure. And there's no excuse for ever seeing a
bad_typeid. Most of the time, you'll probably want to test IO errors
explicitly, rather than configuring the stream to throw exceptions; and
exception when ios_base::badbit is set might be an exception (since it
represents a truly exceptional case of a hardward fault).
Questions 1 and 2 are addressed at some length in this question.
Questions 3 and 5 are covered by the recommendation, in the accepted answer to that question, that you don't use exception specifications at all.
Question 4 seems to be adequately addressed by typing those exception names into the search engine of your choice, or consulting the index of a good C++ book. Do you have a specific query about them?

Avoid slicing of exception types (C++)

I am designing an exception hierarchy in C++ for my library. The "hierarchy" is 4 classes derived from std::runtime_error. I would like to avoid the slicing problem for the exception classes so made the copy constructors protected. But apparently gcc requires to call the copy constructor when throwing instances of them, so complains about the protected copy constructors. Visual C++ 8.0 compiles the same code fine. Are there any portable way to defuse the slicing problem for exception classes? Does the standard say anything about whether an implementation could/should require copy constructor of a class which is to be thrown?
Your exception needs to have a public copy constructor. The compiler has to be able to copy it around for exception handling to work.
The solution to your problem is to always catch by reference instead:
try {
// some code...
throw MyException("lp0 is on fire!");
} catch (MyException const &ex) {
// handle exception
}
(const-ness is optional, but I always put it in because there's rarely a need to modify the exception object.)
Thomas's answer is correct, but I'd also like to suggest you not waste your time by "designing an exception hierarchy". Designing class hierarchies is a notably bad idea, particularly when you could simply derive a couple (and no more than that) of new exception types from the C++ Standard exception classes.
I would steer clear of designing an exception hierarchy distinct to your library. Use the std::exception hierarchy as much as possible and always derive your exceptions from something within that hierarchy. You might want to read the exceptions portion of Marshall Cline's C++ FAQ - read FAQ 17.6, 17.9, 17.10, and 17.12 in particular.
As for "forcing users to catch by reference", I don't know of a good way of doing it. The only way that I have come up with in an hour or so of playing (it is Sunday afternoon) is based on polymorphic throwing:
class foo_exception {
public:
explicit foo_exception(std::string msg_): m_msg(msg_) {}
virtual ~foo_exception() {}
virtual void raise() { throw *this; }
virtual std::string const& msg() const { return m_msg; }
protected:
foo_exception(foo_exception const& other): m_msg(other.m_msg) {}
private:
std::string m_msg;
};
class bar_exception: public foo_exception {
public:
explicit bar_exception(std::string msg_):
foo_exception(msg_), m_error_number(errno) {}
virtual void raise() { throw *this; }
int error_number() const { return m_error_number; }
protected:
bar_exception(bar_exception const& other):
foo_exception(other), m_error_number(other.m_error_number) {}
private:
int m_error_number;
};
The idea is to make the copy constructor protected and force users to call Class(args).raise() instead of throw Class(args). This lets you throw a polymorphicly bound exception that your users can only catch by reference. Any attempt to catch by value should be greeted with a nice compiler warning. Something like:
foo.cpp:59: error: ‘bar_exception::bar_exception(const bar_exception&)’ is protected
foo.cpp:103: error: within this context
Of course this all comes at a price since you can no longer use throw explicitly or you will be greeted with a similar compiler warning:
foo.cpp: In function ‘void h()’:
foo.cpp:31: error: ‘foo_exception::foo_exception(const foo_exception&)’ is protected
foo.cpp:93: error: within this context
foo.cpp:31: error: ‘foo_exception::foo_exception(const foo_exception&)’ is protected
foo.cpp:93: error: within this context
Overall, I would rely on coding standards and documentation stating the you should always catch by reference. Make sure that your library catches exceptions that it handles by reference and throw fresh objects (e.g., throw Class(constructorArgs) or throw;). I would expect other C++ programmers to have the same knowledge - but add a note to any documentation just to be sure.
The two portable ways I have found to stop clients of my library from catching exceptions incorrectly by value are
Throw exceptions from inside virtual raise methods of the exception classes, and make copy constructors protected. (Thanks D.Shawley)
Throw derived exceptions from the library and publish exception base classes for clients to catch. The base classes could have protected copy constructors, which only allows the good way of catching them. (mentioned here for a simmilar question)
The C++ standard does state that copy constructor needs to be accessible at the point of throw. Visual C++ 8.0 in my configuration violated this part of the standard by not enforcing the presence of the copy constructor. In section 15.1.3:
A throw-expression initializes a temporary object, the type of which is determined by removing any top-level cv-qualifiers from the static type of the operand of throw and adjusting the type from “array of T” or “function returning T” to “pointer to T” or “pointer to function returning T”, respectively.
If the use of the temporary object can be eliminated without changing the meaning of the program except for the execution of constructors and destructors associated with the use of the temporary object (12.2), then the exception in the handler can be initialized directly with the argument of the throw expression. When the thrown object is a class object, and the copy constructor used to initialize the temporary copy is not accessible, the program is ill-formed (even when the temporary object could otherwise be eliminated)
This answer was posted by OP into the question, I removed it from the question and posted as a separate answer.
I'd say to not use any of the built in C++ exception code. If you must have exceptions, create your own from scratch. That's the only way to be sure they will behave similar let alone be implemented in a similar manner, and to be blunt the implementation of exceptions in C++ is incompetent.