Is it still safe to delete nullptr in c++0x?
Asked Answered
R

2

115

In c++03 it is pretty clear that deleting a null pointer has no effect. Indeed, it is explicitly stated in §5.3.5/2 that:

In either alternative, if the value of the operand of delete is the null pointer the operation has no effect.

However, in the current draft for c++0x this sentence seems to be missing. In the rest of the draft I could only find sentences stating what happens if the operand of the delete-expression is not the null pointer constant. Is deleting the null pointer still defined in c++0x, and if so, where?

Notes:

There is significant circumstantial evidence to suggest that it is still well defined.

First, there are the two sentences in §5.3.5/2 stating that

In the first alternative (delete object), the value of the operand of delete may be a null pointer value, ...

and

In the second alternative (delete array), the value of the operand of delete may be a null pointer value or ...

These say that the operand is allowed to be null, but on their own do not actually define what happens if it is.

Second, changing the meaning of delete 0 is a major breaking change, and the standards committee would be very unlikely make this particular change. Furthermore there is no mention of this being a breaking change in the Compatibility Annex (Annex C) of the c++0x draft. Annex C is however an Informative section, so this has no bearing no the interpretation of the standard.

On the other hand, the fact that deleting the null pointer is required to have no effect implies an additional run-time check. In a lot of code the operand can never be null, so this runtime check is in conflict with the zero overhead principle. Maybe the committee just decided to change the behaviour to bring standard c++ more in line with the stated design goals of the language.

Rheinland answered 18/7, 2011 at 10:9 Comment(0)
C
136

5.3.5/7 says:

If the value of the operand of the delete-expression is not a null pointer value, the delete-expression will call a deallocation function (3.7.4.2). Otherwise, it is unspecified whether the deallocation function will be called.

And 3.7.4.2/3 says:

The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect.

So the behavior is well defined, as long as the standard deallocation function is used, or a user-provided deallocation function handles null pointers correctly.

Chamfer answered 18/7, 2011 at 10:21 Comment(5)
Since C++14 "If expression evaluates to a null pointer value, no destructors are called, and the deallocation function is not called."Lickspittle
@Lickspittle I don't think that page is correct. The C++14 standard still says "it is unspecified whether the deallocation function will be called" when the pointer is null (5.3.5/7).Chamfer
As an aside, it's not safe to call fclose() for a null file pointer. On Ubuntu (and perhaps other operating systems), fclose(NULL) causes a segmentation fault.Snowinsummer
@GerryBeauregard that's a POSIX file function and has nothing to do with C++ memory management, in my opinion. Closing a file handle has completely different implications, therefore I don't think this comparison is suitable or holds any value for this discussion.Waterfowl
@Lickspittle It seems it was changed, and there was added very important detail: "If expression evaluates to a null pointer value, no destructors are called, and the deallocation function may or may not be called (it's unspecified), but the default deallocation functions are guaranteed to do nothing when passed a null pointer."Deuno
A
10

On the other hand, the fact that deleting the null pointer is required to have no effect implies an additional run-time check.

The new wording does not remove that run-time check for a null pointer. The other way around: draft standard comes even closer to saying that an implementation must make a null pointer test to be compliant.

Also noteworthy: The old standard contradicted itself in that it said (5.3.5/2) that "if the value of the operand of delete is the null pointer the operation has no effect" but later said that (5.3.5/7) the "delete-expression will call a deallocation function." Calling a function is an effect. This is particularly so since the function that is called might well be an overridden operator delete.

The new wording removes that contradiction, explicitly leaving it up to the implementation whether the deallocation function is called in the case of deleting a null pointer.

Abbreviated answered 18/7, 2011 at 10:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.