Skip to content

[expr.delete] p7 The time of calling a deallocation function #4850

Open
@xmh0511

Description

@xmh0511

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

  • [...]
  • 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.
  • Otherwise, the delete-expression will not call a deallocation function.

Consider this example

struct Container{
   char memory[2];
};
auto ptr0 = new Container;  //#0
auto ptr1 = new char;  // #1
auto ptr2 = new char;  //#2
delete ptr1;  //#3
delete ptr2;  //#4
delete ptr0;  //#5

Assume the new-expression at #0 has been extended to provide the storage for #1 and #2. Note the emphasized wording in the second bullet, since there are only two new-expression that use the allocation provided by #0, hence at this point at #4, could we say the delete-expression for every other pointer value(...) has been evaluated? So, the deallocation function shall be called at #4? At the point of #5, the second bullet is also satisfied, hence it again call the deallocation function? Obviously, it does not make sense however it is what the second bullet saying.

I think the second bullet is intend to cover the following case

auto ptr0 = new Container;  //#0
auto ptr1 = new char;  // #1
auto ptr2 = new char;  //#2
delete ptr1;  //#3
delete ptr0;  //#5
delete ptr2;  //#4

This example is based on the first by adjusting the order of the delete-expression whose operand is produced by the extended allocation. The second bullet can work fine in this example, since #4 has not been evaluated, hence #5 cannot invoke the deallocation function, it's the responsibility of #4. However, as aforementioned, the second bullet seems not good at the first example.

Activity

JohelEGP

JohelEGP commented on Aug 31, 2021

@JohelEGP
Contributor

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.

The storage for #0 was also provided by this extended new-expression, so it's accounted for, too.

xmh0511

xmh0511 commented on Aug 31, 2021

@xmh0511
ContributorAuthor

The storage for #0 was also provided by this extended new-expression, so it's accounted for, too.

If you mean the new-expression at #0 provides the storage for itself, it seems impossible, since we should obey [expr.new] p14

The implementation may extend the allocation of a new-expression e1 to provide storage for a new-expression e2 if the following would be true were the allocation not extended:

the evaluation of e1 is sequenced before the evaluation of e2, and

The evaluation of an expression cannot be sequenced before that of itself.

JohelEGP

JohelEGP commented on Aug 31, 2021

@JohelEGP
Contributor

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.

But it does produce a pointer value, which is deleted at #5. That is what is counted.

xmh0511

xmh0511 commented on Aug 31, 2021

@xmh0511
ContributorAuthor

However, the pointer value that is produced by a new-expression has another restriction, which is

that had storage provided by the extended new-expression

As per [expr.new#14], e1 cannot provide storage for itself. Specifically, if we say the delete-expression for ptr0 produced by a new-expression(at #0) that had storage provided by the extended new-expression(at #0) has been evaluated, we claim that extend the allocation of a new-expression(at #0) e1 to provide storage for a new-expression(at #0).

jensmaurer

jensmaurer commented on Aug 31, 2021

@jensmaurer
Member

True, [expr.new] p14 is not applicable for the new-expression that ends up calling the allocation function. However, the understanding is that the allocation function invoked by a new-expression does provide storage for that very new-expression (and possibly for others, as discussed in p14).

xmh0511

xmh0511 commented on Aug 31, 2021

@xmh0511
ContributorAuthor

However, the understanding is that the allocation function invoked by a new-expression does provide storage for that very new-expression (and possibly for others, as discussed in p14).

Yes, however, it's impossible that the new-expresion that has been extended provides the storage for itself as per [expr.new#14.1], except that we say

the evaluation of e1 is sequenced before the evaluation of e2, or e1 is e2, and

jensmaurer

jensmaurer commented on Aug 31, 2021

@jensmaurer
Member

We can certainly say in [expr.new] p10 "A new-expression may obtain storage for the object by calling an allocation function (6.7.5.5.2); the allocation is said to provide storage for the new-expression."

There are simply several options how to provide storage for a new-expression; one is by calling "operator new" and another is by extending an allocation per the p14 rules.

However, I'm hesitant to editorially extend the use of "provides storage" here some more, because [intro.object] p3 uses "provides storage" for a slightly different purpose.

added
decision-requiredA decision of the editorial group (or the Project Editor) is required.
on Aug 31, 2021
xmh0511

xmh0511 commented on Jan 18, 2022

@xmh0511
ContributorAuthor

Since [expr.new] p15 says

The implementation may extend the allocation of a new-expression e1 to provide storage for a new-expression e2.

Hence, to be consistent, [expr.delete] p7 should use the precise utterance

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

  • [...]
  • 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 (allocation of ) 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.

Not the extended new-expression provides the storage for a new-expression, instead, the allocation of the extended new-expression provides that storage.

With the fix: A new-expression may obtain storage for the object by calling an allocation function (6.7.5.5.2); the allocation is said to provide storage for the new-expression.

This issue will be ok.

added
cwgIssue must be reviewed by CWG.
on Jun 12, 2023
added
not-editorialIssue is not deemed editorial; the editorial issue is kept open for tracking.
and removed
decision-requiredA decision of the editorial group (or the Project Editor) is required.
on Jun 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    cwgIssue must be reviewed by CWG.not-editorialIssue is not deemed editorial; the editorial issue is kept open for tracking.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @tkoeppe@xmh0511@JohelEGP@jensmaurer

        Issue actions

          [expr.delete] p7 The time of calling a deallocation function · Issue #4850 · cplusplus/draft