class MyException: public std::logic_error
{
std::string m_string;
public:
MyException(const std::string& arg)
:
std::logic_error(arg), m_string(arg) {}
// A throwing copy-constructor!
MyException(const MyException& arg)
:
std::logic_error(arg), m_string(arg.m_string)
{
// Triggering std::terminate...?
throw std::bad_alloc();
}
~MyException() throw() { }
};
int main()
{
const MyException constException("what");
try
{
// Here the copy-constructor is called:
throw constException;
}
catch( std::bad_alloc & )
{
// Here is where we get!
return EXIT_FAILURE;
}
}
Shouldn't the above test program call std::terminate, instead of
catching the std::bad_alloc?
Martin replied:
AFAIK, the implementation is *allowed* to copy the exception object
but is not required to, so it may just be that at runtime the
copy-ctor is never called.
Thanks, Martin. In some cases, the compiler is indeed allowed to
omit the copy-constructor call. But in this case, I don't think it
is allowed. The test program certainly *does* call the
copy-constructor of MyException, when compiled by VC. So don't you
think it should trigger a call to std::terminate?
Doesn't note 141 from the C++ Working Draft apply here? As follows:
"For example, if the object being thrown is of a class with a copy
constructor, std::terminate() will be called if that copy
constructor exits with an exception during a throw."
See also: Working Draft, Standard for Programming Language C++,
section 15.5.1, The std::terminate() function, [except.terminate],
www.open-std.org/JTC1/sc22/WG21/docs/papers/2009/n3000.pdf
Kind regards,
Niels
create a copy *before* the copy is thrown. This is similar to
evaluating all parameters before calling a function.