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

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.

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).

Throwing exception in destructor of derived class

I am compiling a C++ library, and I have an issue with destructors and noexcept.
It is my understanding that, since C++11, the default value of noexcept(...) inside destructors has changed. In particular, now destructors default to noexcept (that is noexcept(true)).
Now, I have a library for which I get many compiler warnings due to the fact that the destructor of some classes can throw, but it's not marked noexcept(false). So I decided to change that, and add the specification. However, these classes inherited from some common parent Base, so this forced me to add it also to the parent class destructor, otherwise I get the compiler error overriding ‘virtual Base::~Base() noexcept.
Of course, I can add noexcept(false) also to the base class (actually, it is enough to add it there, as far as I understand), but there are lots of classes that inherit from Base, and they would all inherit the noexcept(false) attribute (as far as I understand). However, the base class destructor itself will never throw, and only few of the derived classes can actually throw. Therefore, it appears a waste to mark the base class destructor noexcept(false) only for a few classes.
So, I have two questions:
1) Is there any way around this? I cannot remove the throws in the few derived classes that throw, since they are important.
2) I am not sure how much the compiler optimization could be degraded due to the addition of noexcept(false) to the base class of (virtually) all the classes in the library. When (if ever) should this concern me?
Edit: on a side note, is there a way to change the default value for noexcept inside a project? Perhaps a compiler option?
Edit: since there have been many feedback, I owe an edit, with a few remarks:
1) I did not write the library, and I certainly do not plan to rewrite the destructors of many classes. Having to add a noexcept(false) to a some base classes is already enough of a pain. And resorting to a different library is not an option (for different reasons that go beyond programming).
2) When I said "I cannot remove the throws in the few derived classes that throw, since they are important" I meant that I believe the code should terminate in those case, since something really bad happened and undefined behavior may follow anyways. The throw at least comes with a little explanation of what happened.
3) I understand that throwing in a destructor of a derived class is bad, since it may leak due to the fact that the parent class' destructor is not called (is this correct?). What would be a clean way around if one ought to terminate the program (to avoid obscure bugs later) and still let the user know what happened?
If the destructor is virtual, the derived destructors can't be noexcept(false) unless the base destructor is also noexcept(false).
Think about it: the point of virtual functions is that the derived class can be called even if the caller only knows about the base class. If something calls delete on a Base*, the call may be compiled without any exception-handling code if Base promises that its destructor won't throw exceptions. If the pointer points to a Derived instance whose destructor actually does throw an exception, that would be bad.
Try to change the derived destructors so they don't throw exceptions. If that's not possible, add noexcept(false) to the base destructor.
I am not sure how much the compiler optimization could be degraded due to the addition of noexcept(false) to the base class of (virtually) all the classes in the library. When (if ever) should this concern me?
You should not be concerned about compiler optimizations on the basis of noexcept declarations on destructors. Most of the optimizations around noexcept declarations come from code that detects that an operation is noexcept and does something more efficient based on that. That is, explicit metaprogramming.
Why doesn't that matter for destructors? Well, consider the C++ standard library. If you hand vector a type, and one of the destructors of the contained object throws, you get undefined behavior. This is true for everything in the standard library (unless explicitly noted).
Which means the standard library will not bother to check if your destructor is noexcept or not. It can, and almost certainly will, assume that no destructor emits an exception. And if one does... well, that's your fault.
So your code will likely not run slower just because you use noexcept(false) on a destructor. Your decision of whether to use noexcept(false) on the base class's destructor should not be affected by performance concerns.

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

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.

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...

Is this a safe way of throwing an exception from a destructor?

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.