Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which operations must not throw an exception in C++?

Tags:

Today I learned that swap is not allowed to throw an exception in C++.

I also know that the following cannot throw exceptions either:

  • Destructors
  • Reading/writing primitive types

Are there any others?
Or perhaps, is there some sort of list that mentions everything that may not throw?
(Something more succinct than the standard itself, obviously.)

like image 344
user541686 Avatar asked Jul 23 '12 03:07

user541686


People also ask

Which operation may not throw exception?

I also know that the following cannot throw exceptions either: Destructors. Reading/writing primitive types.

Why can't you throw exceptions from a destructor?

Throwing out of a destructor can result in a crash, because this destructor might be called as part of "Stack unwinding". Stack unwinding is a procedure which takes place when an exception is thrown.

Can you throw exceptions in C?

C doesn't support exceptions. You can try compiling your C code as C++ with Visual Studio or G++ and see if it'll compile as-is. Most C applications will compile as C++ without major changes, and you can then use the try... catch syntax.


1 Answers

There is a great difference between cannot and should not. Operations on primitive types cannot throw, as many functions and member functions, including many operations in the standard library and/or many other libraries.

Now on the should not, you can include destructors and swap. Depending on how you implement them, they can actually throw, but you should avoid having destructors that throw, and in the case of swap, providing a swap operation with the no-throw guarantee is the simplest way of achieving the strong exception guarantee in your class, as you can copy aside, perform the operation on the copy, and then swap with the original.

But note that the language allows both destructors and swap to throw. swap can throw, in the simplest case if you do not overload it, then std::swap performs a copy construction, an assignment and a destruction, three operations that can each throw an exception (depending on your types).

The rules for destructors have changed in C++11, which means that a destructor without exception specification has an implicit noexcept specification which in turn means that if it threw an exception the runtime will call terminate, but you can change the exception specification to noexcept(false) and then the destructor can also throw.

At the end of the day, you cannot provide exception guarantees without understanding your code base, because pretty much every function in C++ is allowed to throw.

like image 168
David Rodríguez - dribeas Avatar answered Sep 23 '22 20:09

David Rodríguez - dribeas