Hi I found this line in a tutorial on web.
What happens when you declare a static object and the destructor throws and exception?
As with static constructor exceptions the application will crash.
I can't seam to understand what's the difference if object is static or not...
Thanks
I'm not sure if you're asking about constructors or destructors that throw exceptions - the problem statement refers to destructors, but the example code and some of the comments refer to constructors.
With regards to constructors that throw, it depends on whether the static object is local or global. Local static objects are constructed the first time that control passes through the scope in which they are defined, and exception handlers should behave normally for them. Global static objects are constructed before the program enters main(); since you can't have a try-catch block at global scope, if the constructor of a global static object throws, it basically means that your application crashes before it makes it out of the starting gate.
As for destructors, generally speaking, destructors that can throw exceptions create serious problems. Herb Sutter details the reasons why in his great book "Exceptional C++", which is available here on Google Books. Basically, if a destructor can throw exceptions, it makes it nearly impossible to write exception-safe code. Consider the following example.
class T
{
T() {}
~T() { throw 5; }
};
void foo()
{
T t;
throw 10;
}
When foo() reaches the throw 10; statement, control will exit the context of foo(), destroying the local object t in the process. This calls the destructor for t, which tries to throw another exception. In C++, it isn't possible to throw two exceptions simultaneously; if a second exception is thrown like this, the program calls the built-in function terminate(), which does what it sounds like and terminates the program (you can set your own function to be called instead using set_terminate, but this is mostly for doing custom clean-up - you can't change the fact that the program ends after the function is done).
The way to avoid this is to make sure that destructors never throw exceptions. It may not matter with static objects, because as celtschk noted the destructor won't be called until the program is terminating anyway, but as a general rule, if you find yourself writing a class with a destructor that can throw an exception, you should think carefully about whether it is really the best approach.
Related
Consider the following piece of code for C++:
class A {
A() {
if(some condition)
exit(1);
}
};
Is this legitimate to do? i.e. exiting directly from a constructor before it has completed. Are there any side effects to this?
Yes, this is legal C++. However, be aware that this doesn't unwind the stack like a call to throw; would do, so the destructors of any stack-allocated variables will not be called. But it will call the destructor of static variables. See the documentation of std::exit() for more information.
Is this legitimate to do?
Technically yes. That said, I cannot think of a reasonable use case.
Are there any side effects to this?
exit has effect of terminating the process (static objects are destroyed; automatic objects are not). Calling it within a constructor doesn't change that.
There are different points of view:
Is it correct code from a compiler point of view?
Yes. The exit function can be called at any point from a C++ program and will cause the program to exit as soon as possible.
Are there possible unexpected side effects?
Yes. The destructors of any members or base classes of the object under construction will not be called. For example if some of them were responsible for writing data on disk that should be used on next start, that data might not be written.
Is there any case where it is legitimate code?
No. If you need to abort inside an object constructor, you should throw an exception. If the exception is not caught, it will indeed abort the program, but in a clean way, ensuring that any constructed objects (even members of the object in construction) will have its destructor called. And any caller will have an opportunity to do some clean up.
Long story made short: NEVER DO THAT!
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.
This question already has answers here:
Are destructors called after a throw in C++?
(3 answers)
Closed 9 years ago.
I have a code such as this:
class myclass
{
myclass()
{
// doing some init here
}
~myclass()
{
// doing some important clean up here
}
void Do()
{
// doing some work which may throw exception
}
}
and I am using this class in this way:
MyFunction()
{
myclass mc;
mc.do();
}
My question is :
If there is an exception in do function, what would happen? Is destructor of myclass called?
If no, what is the best way to handle this type of situations? Assume that I don't have the source code and I am sure about what is happening in destructor.
If there is an exception in do function, what would happen?
If you have any handler, it will be handled.
Is destructor of myclass called?
Yes, definitely. The standard quotes this::
An object of any storage duration whose initialization or destruction
is terminated by an exception will have destructors executed for all
of its fully constructed subobjects (excluding the variant members of
a union-like class), that is, for subobjects for which the principal
constructor (12.6.2) has completed execution and the destructor has
not yet begun execution. Similarly, if the non-delegating constructor
for an object has completed execution and a delegating constructor for
that object exits with an exception, the object’s destructor will be
invoked. If the object was allocated in a new-expression, the matching
deallocation function (3.7.4.2, 5.3.4, 12.5), if any, is called to
free the storage occupied by the object.
This whole process is known as "stack unwinding":
The process of calling destructors for automatic objects constructed
on the path from a try block to a throw-expression is called “stack
unwinding.” If a destructor called during stack unwinding exits with
an exception, std::terminate is called (15.5.1).
C++11 15.5.1 The std::terminate() function [except.terminate]
2 … In the situation where no matching handler is found, it is
implementation-defined whether or not the stack is unwound before
std::terminate() is called.
If the exception is caught somewhere, then stack unwinding will guarantee that the destructor is called for this object (and, in general, all automatic variables that go out of scope as a result of the exception). This is a very important guarantee, without which we could not use techniques like RAII to write exception-safe code.
If the exception is not caught, then the program will be terminated, and it's implementation-dependent whether or not the stack will be unwound first. If it's important to destroy the object cleanly even in that situation, then one option is to catch and rethrow the exception, outside the object's scope.
If the program is ended in some other way, e.g. by calling exit() or terminate(), or receiving an unhandled signal, then the stack won't be unwound. If you need clean destruction in these situations, then things will get messy.
C++ does not have explicit "finally" clauses like many other languages, but instead you rely in "RAII" which essentially is a technique of using scoped "automatic" variables and relying on the fact that their destructor will get called at the appropriate moment when they go out of scope.
In your case the destructor of myclass will be called even if mc.do() throws an exception. In a lot of these "closure" issues, the object you put at the top of the scope block is a class that is used only for the purpose of invoking the destructor on termination.
The "D" language comes with a special closure syntax. There have been attempts to write libraries that do that in C++ and with lambdas it is certainly easier to write than now than it used to be although I do not think they are a formal part of C++ as yet.
As I know, std::string is a RAII object so I don't need to initialize after declaration. The constructor will take care of this stuff automatically. But is there any exception on any platform or any compiler ?
class TestString
{
public:
TestString()
{
// m_str.clear(); or
// m_str = "";
}
virtual ~TestString(){}
private:
std::string m_str;
};
Very simple question, thanks !
The default constructor for std::string constructs an empty string, with a length of zero characters. That is the guarantee offered by the default constructor on all platforms for all implementations.
In C++, initialisation may involve several method calls after construction, but this doesn't violate RAII. It's the constructors responsibility to get the object into a self-consistent valid state - in particular, one where it's safe to call the destructor or any other method. Depending on your requirements, this may mean nothing more than setting some variables to zero.
So why the big fuss about RAII? Well, the original point of RAII (Resource Allocation Is Initialisation) related to exception safety.
When a function exits early, in particular due to an exception throw, it's important that destructors are called - that resources (heap memory and file handles, for example) are released. C++ mandates that destructor calls occur automatically when a variable goes out of scope for that reason. However, an exception throw can happen at any time, at least in principle. How can you be sure that the resource you want to release has even been allocated? If your not sure that that allocation will have been done you could use a flag or a null handle or similar so you can test in the destructor, but how can you be sure that flag has been initialised?
Basically, in order to be able to call a destructor safely, C++ needs to know that the object has been initialised. That is handled by the constructor. But that just leads to another subtle issue - what happens if an exception throw occurs inside the constructor.
Long story short - C++ takes responsibility for the destructor call only after the constructor has successfully completed. If the constructor is exited early by an exception throw, there will be no destructor call - if exceptions haven't been handled carefully (or proven impossible) within the constructor, memory and/or resource leaks may occur.
Anyway, the origin of the name is simply that resources aren't considered to have been acquired unless the constructor has completed, therefore freeing resources (by calling the destructor) should occur if and only if the constructor completed successfully.
That's a simple model, though, and the name can be misleading. In practice, resources can be acquired by any method, and the language has no fixed ideas about which kinds of activity are initialisation and which aren't. The important thing is that, if an exception is thrown at an awkward moment and your objects destructor is called as a result, it should always be able to determine exactly what cleanup is needed - which resources to release.
Constructing an object in a self-consistent state isn't a difficult job - it may require no more than setting some member variables to zero. In fact some people strongly recommend that you do no more than this in most classes, the reason being that setting a few POD member variables to zero cannot trigger an exception throw - you don't have to worry about catching and rethrowing exceptions and cleaning up that semi-constructed object.
Every standard library class that has a destructor will meet that self-consistent state requirement. Only "Plain Old Data" types (e.g. int) which by definition don't have destructors (well, no useful destructors at least) don't implement RAII, at least not for themselves.
I know that throwing from a destructor is in general a bad idea, but I was wondering if i could use std::uncaught_exception() to safely throw from a destructor.
Consider the following RAII type:
struct RAIIType {
...
~RAIIType() {
//do stuff..
if (SomethingBadHappened()) {
//Assume that if an exception is already active, we don't really need to detect this error
if (!std::uncaught_exception()) {
throw std::runtime_error("Data corrupted");
}
}
}
};
Is this UB in c++11? Is it a bad design?
You have an if, did you think about the "other" condition? It can throw an exception or... do what? There's two things that can be in the other branch.
Nothing (If nothing needs to happen when the error occurs, why throw an exception?)
It "handles" the exception (If it can be "handled", why throw an exception?)
Now that we've established that there's no purpose to throwing an exception conditionally like that, the rest of the question is sort of moot. But here's a tidbit: NEVER THROW EXCEPTIONS FROM DESTRUCTORS. If an object throws an exception, the calling code normally checks that object in some way to "handle" the exception. If that object no longer exists, there's usually no way to "handle" the exception, meaning the exception should not be thrown. Either it's ignored, or the program makes a dump file and aborts. So throwing exceptions from destructors is pointless anyway, because catching it is pointless. With this is mind, classes assume that destructors won't throw, and virtually every class leaks resources if a destructor throws. So NEVER THROW EXCEPTIONS FROM DESTRUCTORS.
Note that your code doesn't do what you think it does. In case SomethingBadHappened and there is no stack unwinding in place, you attempt to throw from a destructor and nonetheless std::terminate is called. This is the new behavior in C++11 (see this article). You will need to annotate your destructor with noexcept(false) specification.
Suppose you do this, it is not clear what you mean by "safely". Your destructor never triggers std::terminate directly. But calling std::terminate is not a UB: it is very well defined and useful (see this article).
For sure, you cannot put your class RAIIType into STL containers. The C++ Standard explicitly calls that UB (when a destructor throws in an STL container).
Also, the design look suspicious: the if-statement really means "sometimes report a failure and sometimes not". Are you fine with this?
See also this post for a similar discussion.
I know that throwing from a destructor is in general a bad idea, but I was wondering if i could use std::uncaught_exception() to safely throw from a destructor.
You may like to have a look at uncaught_exceptions proposal from Herb Sutter:
Motivation
std::uncaught_exception is known to be “nearly useful” in many situations, such as when implementing an Alexandrescu-style ScopeGuard. [1]
In particular, when called in a destructor, what C++ programmers often expect and what is basically true is: “uncaught_exception returns true iff this destructor is being called during stack unwinding.”
However, as documented at least since 1998 in Guru of the Week #47, it means code that is transitively called from a destructor that could itself be invoked during stack unwinding cannot correctly detect whether it itself is actually being called as part of unwinding. Once you’re in unwinding of any exception, to uncaught_exception everything looks like unwinding, even if there is more than
one active exception.
...
This paper proposes a new function int std::uncaught_exceptions() that returns the number of exceptions currently active, meaning thrown or rethrown but not yet handled.
A type that wants to know whether its destructor is being run to unwind this object can query uncaught_exceptions in its constructor and store the result, then query uncaught_exceptions again in its destructor; if the result is different, then this destructor is being invoked as part of stack unwinding
due to a new exception that was thrown later than the object’s construction.
It depends what you mean by "safely".
That will prevent one of the issues with throwing from a destructor - the program won't be terminated if the error happens during stack unwinding when handling another exception.
However, there are still issues, among them:
If you have an array of these, then they may not all be destroyed if one throws on destruction.
Some exception-safety idioms rely on non-throwing destruction.
Many people (such as myself) don't know all the rules governing what will or won't be correctly destroyed if a destructor throws, and won't be confident that they can use your class safely.