Calling delete on NULL pointers - C++03 vs C++11
Asked Answered
C

2

21

In the C++03 Standard, I see:

5.3.5 Delete

2 If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section. In either alternative, if the value of the operand of delete is the null pointer the operation has no effect. In the first alternative (delete object), the value of the operand of delete shall be a pointer to a non-array object or a pointer to a sub-object (1.8) representing a base class of such an object (clause 10). If not, the behavior is undefined. In the second alternative (delete array), the value of the operand of delete shall be the pointer value which resulted from a previous array new-expression.72) If not, the behavior is undefined.

In the C++11 Draft Standard (N3337), I see:

5.3.5 Delete

2 If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section. In the first alternative (delete object), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined. In the second alternative (delete array), the value of the operand of delete may be a null pointer value or a pointer value that resulted from a previous array new-expression. If not, the behavior is undefined.

I have highlighted the differences between the specifications in the two standards. I find it strange that the 2003 standard was more emphatic on how NULL pointers must be dealt with while the 2011 standard says nothing about what an implementation must do.

  1. Did the verbiage of the C++11 standard change between the draft standard and the actual standard? If so, how?

  2. If the verbiage of the draft standard remains unchanged in the actual standard, what was the rationale for changing a very strong statement to almost nothing between 2003 and 2011?

Chouinard answered 15/8, 2014 at 15:44 Comment(0)
S
24

It looks like we can find a rationale for this change in defect report 348, which says:

Specifically, standard says in 5.3.5 [expr.delete] paragraph 2:

...if the value of the operand of delete is the null pointer the operation has no effect.

Standard doesn't specify term "has no effect". It is not clear from this context, whether the called deallocation function is required to have no effect, or delete-expression shall not call the deallocation function.

Furthermore, in para 4 standard says on default deallocation function:

If the delete-expression calls the implementation deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation]), if the operand of the delete expression is not the null pointer constant, ...

Why it is so specific on interaction of default deallocation function and delete-expr?

If "has no effect" is a requirement to the deallocation function, then it should be stated in 3.7.4.2 [basic.stc.dynamic.deallocation], or in 18.6.1.1 [new.delete.single] and 18.6.1.2 [new.delete.array], and it should be stated explicitly.

part of the resolution was the change in wording that you noted, although the language around that phrasing has changed quite a bit but the logic of getting rid of the has no effect language still stands, it is not a well defined term and so should be replaced with well specified language.

Stowers answered 15/8, 2014 at 15:50 Comment(1)
The defect report is good. Its recommendation "then it should be stated in 3.7.4.2" is rational. The resolution is botched, since it doesn't do that: deallocation functions can still be called with null arguments, making the whole thing, the C++11 guarantee for no such calls from delete-expressions, meaningless, of no practical value.Emphasize
B
10

The latest C++14 draft (N3797) has roughly equivalent wording in this section. But the behaviour is equally-strongly specified, just not in quite the same paragraph.

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

If the value of the operand of the delete-expression is not a null pointer value, then: — If the allocation call for the new-expression for the object to be deleted was not omitted ( 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. — Otherwise, the delete-expression will not call a deallocation function ( 3.7.4.2 ).

These paragraphs are clearly just as strong as C++03. The Committee could not have broken the behaviour of programs which delete null pointers, as these are widespread and the cost of fixing would be much too large. It would have made C++11 unimplementable.

Bipack answered 15/8, 2014 at 15:51 Comment(9)
It's difficult to imagine any real problem that this change could have solved. Looks like politics to me. Can I has a wording change pl3z, just any?Emphasize
The DR in the other answer clearly shows what problem the change solved.Bipack
i fail to see the finer details of how "no effect" is achieved, as a problem. writing a custom deallocation function and relying on a C++11 guarantee that it will not be called with 0, is asking for trouble.Emphasize
Then that's your fault, because the Standard authors clearly did.Bipack
re "the Standard authors clearly did", no that (silly authority argument) does not follow. the list of DRs is pretty long. each DR is testimony that the authors of some part of the standard did not fully understand things.Emphasize
Added to that, §3.7.4.2/4 "If the argument given to a deallocation function in the standard library is a pointer that is not the null pointer value (4.10), the deallocation function shall" implies that a deallocation function can be called with a nullpointer. Makes the guarantee about no such call from delete-expression pretty moot.Emphasize
Tell it to CWG, because I really don't care.Bipack
Re "I really don't care", you cared enough about something that you have attempted to argue against my observation with first a plain assertion, then an authority argument fallacy, and now feigned indifference. Is it the technical stuff you don't care about then? Is what you care about (enough to do this) of entirely non-technical nature?Emphasize
N3936 S5.3.5/7 contains the wording Otherwise, it is unspecified whether the deallocation function will be called. Clearly the standard is not going to provide the guarantee OP wants.Catalepsy

© 2022 - 2024 — McMap. All rights reserved.