noexcept
and exception guarantees
How does the noexcept
specifier relate to exception safety guarantees in C++?
The noexcept
specifier is closely related to exception safety guarantees in C++. Exception safety refers to the guarantees that a function or a class provides regarding its behavior when exceptions are thrown.
There are three main levels of exception safety guarantees:
- Basic guarantee: If an exception is thrown, the program is left in a valid but unspecified state. No resources are leaked, and all invariants are maintained.
- Strong guarantee: If an exception is thrown, the state of the program is rolled back to the state it was in before the function was called. This means that either the function completely succeeds or has no effect at all.
- No-throw guarantee: The function guarantees that it will not throw any exceptions and will always succeed.
The noexcept
specifier is used to indicate that a function provides the no-throw guarantee. When a function is marked as noexcept
, it promises not to throw any exceptions. If an exception is thrown from a noexcept
function, the program will terminate by calling std::terminate()
.
Here's an example illustrating the relationship between noexcept
and exception safety guarantees:
#include <iostream>
void basicGuarantee() {
// Function provides basic guarantee
// ...
}
void strongGuarantee() {
// Function provides strong guarantee
// ...
}
void noThrowGuarantee() noexcept {
// Function provides no-throw guarantee
// // ...
}
int main() {
try {
basicGuarantee();
strongGuarantee();
noThrowGuarantee();
} catch (...) {
std::cout << "Exception caught\n";
}
}
In this example:
basicGuarantee()
provides the basic exception safety guarantee. If an exception is thrown, the program is left in a valid state, but the exact state is unspecified.strongGuarantee()
provides the strong exception safety guarantee. If an exception is thrown, the state of the program is rolled back to the state before the function was called.noThrowGuarantee()
is marked asnoexcept
, indicating that it provides the no-throw guarantee. It promises not to throw any exceptions.
By using noexcept
, you communicate to the compiler and other parts of the program that a function guarantees not to throw exceptions. This information can be used for optimization purposes and to ensure that the function can be safely used in contexts where exceptions are not allowed or would lead to undefined behavior.
It's important to note that marking a function as noexcept
comes with the responsibility of ensuring that the function indeed does not throw any exceptions. If an exception is thrown from a noexcept
function, it will lead to program termination.
Using std::terminate()
and the noexcept
Specifier
This lesson explores the std::terminate()
function and noexcept
specifier, with particular focus on their interactions with move semantics.