C++ std::string is 100% RAII on any platform? - c++

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.

Related

The correct way to throw exception from constructors without encapsulation in C++?

There are already several questions about this on StackOverflow but none of them adequately capture the nature of throwing exceptions from constructors and the memory implication of doing such in certain cases.
What I'd like to ask is about the memory safety of throwing an exception during construction, assuming we have several allocation objects in construction.
From what I understand (what we've been taught) is that if an exception is thrown from the constructor, then the destructor doesn't have a guarantee to be called, so the object could be left in an inconsistent state. Not sure if I interpreted that correctly.
So if we have objects such as vectors of deques in a more complex constructor (assuming we aren't using an Init() method so we don't violate RAII), could this mean their memory doesn't get released?.. Or do they get destructed because they're in the scope of the constructor?..
Another point of view is if we have a deque as a private variable of the class, and we add items to it during construction, which then fails. Since this deque was made during initialization, does it mean it won't get destructed / released when an exception is thrown during object construction, leading to a potential leak?
This is all assuming we're not using a separate class to encapsulate our throwing class, to catch exceptions and handle them alone.
What is the safest way to throw an exception during construction, taking all of this in mind? Should we manually call the destructor before throwing, in case we have manual memory allocations and whatnot?

How bad is not freeing up memory right before the end of program?

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.

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.

Under what circumstances are C++ destructors not going to be called?

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.

Class destructor memory handling in C++

What potential memory leaks won't an implicit destructor handle? I know that if you have anything stored on the heap it won't handle it, and if you have a connection to a file or a database, that needs to be handled manually. Is there anything else? What about, say, non-base data types like vectors?
Also, in an explicit destructor, need you destroy non-heap variables which would have been destroyed by the implicit, or are they handled automatically?
Thanks
vectors and the like will deallocate themselves because their destructor is called.
In fact your problem will lie with anything that would cause a problem of a dangling pointer (or handle or whatever), ie anything that needs to be manually Closed or de-allocated won't be in an implicit destructor. Anything that destructs itself properly will be fine. This is why the RAII idiom is so popular :)
I think the question is upside-down. Don't think in terms of what object destruction doesn't do: think in terms of what it does do.
If a class only has an implicit destructor, then when it is destroyed, all non-static data members are destroyed too, as are all base-class sub-objects.
You can argue a bit whether this is done "by the implicit destructor" or not - if you write a destructor, those things still happen. It's part of the object destruction process itself, rather than part of the code of the destructor as such.
So, if your "connection to a file" is a FILE* class member, then the default destructor doesn't release it, because FILE* is a C thing, and it doesn't have a destructor. Destroying a FILE* does nothing. If your "connection to a file" is a std::ofstream, then it does have a destructor, and the destructor tries to flush and close the connection.
Vector has a destructor which release the vector's resources. This means that in turn the elements in the vector have their destructors called.
For each member variable you have, you should look at the corresponding documentation to see how resources are handled for that type. Obviously with experience, you start to remember the answers.
If the member variable is a pointer, then the implicit destructor doesn't do anything with it. So if it points to heap-allocated memory, and this object holds the only pointer to that memory, then you need to free it to avoid a memory leak.
If you find yourself writing a destructor in C++ that needs to free more than one thing, then you've probably designed the class badly. There are almost certainly exception-safety errors elsewhere in the class: it's possible to get the code right, but if you're experienced enough to get it right then you're experienced enough to make your own life easier by designing it differently ;-). The solution is to write classes with a single responsibility -- to manage a single resource -- and use them as member variables. Or, better, to find library classes that manage the resource you're using. shared_ptr is pretty flexible.
"need you destroy non-heap variables"
There is no such thing in C++ as "heap" and "non-heap" variables. Destroying a pointer does not free the thing pointed to, for the obvious reason that nothing in the type of a pointer tells you how the thing it points to was allocated, or who "owns" it.
You need to understand three things about destructors. Say you have an object t of class T with three members.
class T
{
A a;
B b;
C c;
// ...
} t;
Destructing t ALWAYS means calling the following destructors in that order: ~T(), ~C(), ~B(), ~A(). You cannot influence these semantics. It is impossible to prevent the destruction of the members. This ALWAYS happens, no matter if you define ~T() manually or if the compiler generates it.
Implicitly generated destructors are ALWAYS a no-op. However, as stated in point 1, the destructors ~C(), ~B() and ~A() will still be executed afterwards.
The destructors of scalar types, especially C-style pointers, are ALWAYS a no-op. This is the sole reason why you almost always need to write the destructor (and the copy constructor and the assignment operator) manually when you have a C-style pointer member -- after ~T() has finished, destructing a C-style pointer member does NOTHING, so any cleanup intended on the pointees has to be done in ~T().
I hope this clears things up for you.
What potential memory leaks won't an implicit destructor handle? I know that if you have anything stored on the heap it won't handle it, and if you have a connection to a file or a database, that needs to be handled manually. Is there anything else? What about, say, non-base data types like vectors?
To put it simply, you are correct. The only thing not handled by the implicit destructor is memory allocated in the form of a pointer or another type of resource that needs to be released explicitly.
With regard to vectors or any other class type objects; all classes have a destructor which takes care of releasing their data. The destructor of an object of this type is called when it goes out of scope. All basic data types like: int, float, double, short, bool etc are released in similar fashion.
Also, in an explicit destructor, need you destroy non-heap variables which would have been destroyed by the implicit, or are they handled automatically?
The answer to this is that they are handled automatically, in fact you should never ever try to explicitly call the destructor of an object.
In an implicit destructor the following occurs:
Each of the member variables of the class have their destructors called in turn.
In an explicit destructor the following occurs:
The body of the explicit destructor is executed
Each of the member variables of the class have their destructors called in turn.
So you can see that an explicit destructor is much the same as an implicit one, except that you can take any necessary manual intervention.
Now as a bit of advice with regard to managing memory allocated objects you should pretty much always use RAII (resource acquisition is initialisation). The crux of this is smart pointers, these are pointers that are deleted correctly when they go out of scope just like non heap allocated objects. Ownership becomes an issue once you start using them but that's a story for another day. A good place to start with smart pointers is boost::shared_ptr. (btw if you haven't got on board with boost yet and you write c++ code do yourself a favour...)
The implicit destructor calls the destructor on all member variables.
If you have a raw pointer, its destructor does nothing. So if you own the memory it points to, you have to release it explicitly.
The same applies to any other resource, or any other action you wish to take not implied by the default destructor of the member variable.
The default destructors of members are still called, so vectors, auto_ptrs, files opened using std streams or other C++ libraries all get destroyed. The moral is to wrap any OS objects which need releasing in C++ classes which tidy themselves up, so that application classes don't have to worry about it.
A class' destructor will implicitely call the destructors of all non-static members, then the destructors of virtual base classes, then its own code.
If you have STL containers as class members, you don't have to do anything explicitely--they will free their own memory in their destructors.
You're already making wrong assumptions. If my class holds heap-allocated data using an std::auto_ptr<Data>, the implicit dtor will handle it. No memory will be leaked. The reason is that the implict dtor, like any other dtor, will call the dtors of all members and base classes.
Now, a good class design holds all important resources as members with proper dtors. As a result, the dtor body needs to do nothing to prevent resource leaks. Of course, there is one exception to that rule: resource managing classes themselves manage precisely one resource, and therefore clean up that one resource in their dtor.