Exception safety is the state of code working correctly when exceptions are thrown.[1] To aid in ensuring exception safety, C++ standard library developers have devised a set of exception safety levels, contractual guarantees of the behavior of a data structure's operations with regards to exceptions. Library implementers and clients can use these guarantees when reasoning about exception handling correctness. The exception safety levels apply equally to other languages and error-handling mechanisms.[2]
As David Abrahams writes, "nobody ever spoke of 'error-safety' before C++ had exceptions."[3] The term appeared as the topic of publications in JTC1/SC22/WG21, the C++ standard committee, as early as 1994.[4] Exception safety for the C++ standard library was first formalized for STLport by Abrahams, establishing the basic safety/strong safety distinction.[5] This was extended to the modern basic/strong/nothrow guarantees in a later proposal.[6]
Exceptions provide a form of non-local control flow, in that an exception may "bubble up" from a called function. This bubbling can cause an exception safety bug by breaking invariants of a mutable data structure, as follows:[7]
finally
block is enteredCode with a bug such as the above can be said to be "exception unsafe".[7]
The C++ standard library provides several levels of exception safety (in decreasing order of safety):[8]
Usually, at least basic exception safety is required to write robust code. Higher levels of safety can sometimes be difficult to achieve, and might incur an overhead due to extra copying. A key mechanism for exception safety is a finally
clause, or similar exception handling syntax, which ensure that certain code is always run when a block is exited, including by exceptions. Several languages have constructs that simplify this, notably using the dispose pattern, named as using
, with
, or try
-with-resources.
Consider a smart vector type, such as C++'s
std::vector
or Java's
ArrayList
. When an item
x
is added to a vector
v
, the vector must actually add
x
to the internal list of objects and update a count field that says how many objects are in
v
. It may also need to allocate new memory if the existing capacity isn't sufficient.
Exception safety alternatives:
insertfunction's behavior on allocation failure (for example, by having the function return a boolean result indicating whether the insertion took place).
xinto
vsucceeds, or
vremains unchanged despite the allocation failure.
v. For example, if an error is encountered, the
insertfunction might completely deallocate
vand reset its count field to zero. On failure, no resources are leaked, but
v's old value is not preserved.
v, an incorrect value in the count field, or a resource leak.
Original source: https://en.wikipedia.org/wiki/Exception safety.
Read more |