Why is an overloaded delete not called when an exception is thrown in a destructor?

后端 未结 3 1839
温柔的废话
温柔的废话 2021-01-12 02:39

I\'ve written the below code which overloads the new and delete operators and throws an exception in the destructor.

When the exception is

3条回答
  •  有刺的猬
    2021-01-12 03:14

    In the 1998 C++ standard (ISO/IEC 14882 First edition, 1998-09-01) the workings of a delete expression are stated quite simply in "Section 5.3.5 Delete [expr.delete]" in paras 6 and 7.

    6 The delete-expression will invoke the destructor (if any) for the object or the elements of the array being deleted. In the case of an array, the elements will be destroyed in order of decreasing address (that is, in reverse order of the completion of their constructor; see 12.6.2).

    7 The delete-expression will call a deallocation function (3.7.3.2).

    In combination, these clauses require that destructor will be invoked (or destructors for an array) and that the deallocation function will be called unconditionally. There is no provision here for not calling the deallocation function if an exception is thrown.

    In the 1998 standard, language lawyers and compiler developers will probably take delight in the sophistry of arguing a different interpretation than I've stated above. Fortunately, things are more explicit in later standards...

    In Draft N4296 available from open-std.org the same clauses are expanded as follows: (from memory the wording in the official standard is the same, but I don't have a copy on my current machine)
    (emphasis mine)

    6 If the value of the operand of the delete-expression is not a null pointer value, the delete-expression will invoke the destructor (if any) for the object or the elements of the array being deleted. In the case of an array, the elements will be destroyed in order of decreasing address (that is, in reverse order of the completion of their constructor; see 12.6.2).

    7 If the value of the operand of the delete-expression is not a null pointer value, then:

    (7.1) - If the allocation call for the new-expression for the object to be deleted was not omitted and the allocation was not extended (5.3.4), the delete-expression shall call a deallocation function (3.7.4.2). The value returned from the allocation call of the new-expression shall be passed as the first argument to the deallocation function.

    (7.2) - Otherwise, if the allocation was extended or was provided by extending the allocation of another new-expression, and the delete-expression for every other pointer value produced by a new-expression that had storage provided by the extended new-expression has been evaluated, the delete-expression shall call a deallocation function. The value returned from the allocation call of the extended new-expression shall be passed as the first argument to the deallocation function.

    (7.3) - Otherwise, the delete-expression will not call a deallocation function (3.7.4.2).

    Otherwise, it is unspecified whether the deallocation function will be called. [Note: The deallocation function is called regardless of whether the destructor for the object or some element of the array throws an exception.end note]

    The note at the end spells out that the deallocation function must be called even if the destructor throws an exception.

    I'm unsure offhand which evolution of the standard first spelled things out, but based on the above, the clauses will probably remain in Section 5.3.5 (tag [expr.delete]).

提交回复
热议问题