I know that my destructors are called on normal unwind of stack and when exceptions are thrown, but not when exit() is called.
Are there any other cases where my destructors are not going to get called? What about signals such as SIGINT or SIGSEGV? I presume that for SIGSEGV, they are not called, but for SIGNINT they are, how do I know which signals will unwind the stack?
Are there any other circumstances where they will not be called?
Are there any other circumstances where they[destructors] will not be called?
Long jumps: these interfere with the natural stack unwinding process and often lead to undefined behavior in C++.
Premature exits (you already pointed these out, though it's worth noting that throwing while already stack unwinding as a result of an exception being thrown leads to undefined behavior and this is why we should never throw out of dtors)
Throwing from a constructor does not invoke the dtor for a class. This is why, if you allocate multiple memory blocks managed by several different pointers (and not smart pointers) in a ctor, you need to use function-level try blocks or avoid using the initializer list and have a try/catch block in the ctor body (or better yet, just use a smart pointer like scoped_ptr since any member successfully initialized so far in an initializer list will be destroyed even though the class dtor will not be called).
As pointed out, failing to make a dtor virtual when a class is deleted through a base pointer could fail to invoke the subclass dtors (undefined behavior).
Failing to call matching operator delete/delete[] for an operator new/new[] call (undefined behavior - may fail to invoke dtor).
Failing to manually invoke the dtor when using placement new with a custom memory allocator in the deallocate section.
Using functions like memcpy which only copies one memory block to another without invoking copy ctors. mem* functions are deadly in C++ as they bulldoze over the private data of a class, overwrite vtables, etc. The result is typically undefined behavior.
Instantiation of some of smart pointers (auto_ptr) on an incomplete type, see this discussion
The C++ standard says nothing about how specific signals must be handled - many implementations may not support SIGINT, etc. Destructors will not be called if exit() or abort() or terminate() are called.
Edit: I've just had a quick search through the C++ Standard and I can't find anything that specifies how signals interact with object lifetimes - perhaps someone with better standards-fu than me could find something?
Further edit: While answering another question, I found this in the Standard:
On exit from a scope (however
accomplished), destructors (12.4) are
called for all constructed objects
with automatic storage duration
(3.7.2) (named objects or temporaries)
that are declared in that scope, in
the reverse order of their
declaration.
So it seems that destructors must be called on receipt of a signal.
Another case they won't be called is if you are using polymorphism and have not made your base destructors virtual.
A signal by itself won't affect the execution of the current thread and hence the invocation of destructors, because it is a different execution context with its own stack, where your objects do not exist. It's like an interrupt: it is handled somewhere outside of your execution context, and, if handled, the control is returned to your program.
Same as with multithreading, C++ the language does not know a notion of signals. These two are completely orthogonal to each other and are specified by two unrelated standards. How they interact is up to the implementation, as long as it does not break either of the standards.
As a side note, another case is when object's destructor won't be called is when its constructor throws an exception. Members' destructors will still be called, though.
abort terminates program without executing destructors for objects of automatic or static storage duration as Standard says. For other situations you should read implementation specific documents.
If a function or method has a throws specification, and throws something NOT covered by the specification, the default behavior is to exit immediately. The stack is not unwound and destructors are not called.
POSIX signals are an operating system specific construct and have no notion of C++ object scope. Generally you can't do anything with a signal except maybe, trap it, set a global flag variable, and then handle it later on in your C++ code after the signal handler exits.
Recent versions of GCC allow you to throw an exception from within synchronous signal handlers, which does result in the expected unwinding and destruction process. This is very operating system and compiler specific, though
A lot of answers here but still incomplete!
I found another case where destructors are not executed. This happens always when the exception is catched across a library boundary.
See more details here:
Destructors not executed (no stack unwinding) when exception is thrown
There are basically two situations, where destructors are called: On stack unwind at the end of function (or at exceptions), if someone (or a reference counter) calls delete.
One special situation is to be found in static objects - they are destructed at the end of the program via at_exit, but this is still the 2nd situation.
Which signal leaves at_exit going through may depend, kill -9 will kill the process immediately, other signals will tell it to exit but how exactly is dependent on the signal callback.
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!
As an example let's talk about singleton implementation using new (the one where you create the actual instance at the first call to getInstance() method instead of using a static field. It dawned on me that it never frees that memory up. But then again it would have to do it right before the application closes so the system will free that memory up anyway.
Aside from bad design, what practical downsides does this approach have?
Edit: Ad comments - all valid points, thanks guys. So let me ask this instead - for a single thread app and POD singleton class are there any practical downsides? Just theoretically, I'm not going to actually do that.
for a single thread app and POD singleton class are there any practical downsides? Just theoretically, I'm not going to actually do that.
in standardese
[c++14-Object lifetime-4]For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.
where the dtor is implicitly called on automatic/static variables and such.
So, (assuming a new expression were used to construct the object) the runtime implementation of the invoked allocation function is free to release the memory and let the object decay in oblivion, as long as no observable effects depends on its destruction ( which is trivially true for types with trivial dtors ).
Use a schwartz counter for all singleton types. It's how std::cout is implemented.
Benefits:
thread safe
correct initialisation order guaranteed when singletons depend on each other
correct destruction order at program termination
does not use the heap
100% compliant with c++98, c++03, c++11, c++14, c++17...
no need for an ugly getInstance() function. Just use the global object.
https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter
As for the headline question:
How bad is not freeing up memory right before the end of program?
Not freeing memory is not so bad when the program is running under an OS which manages process memory.
However, other things that singletons do could include flushing IO buffers (e.g. std::cout, std::cerr). That's probably something you want to avoid losing.
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.