C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Relax the restriction on the operand of a single-object delete-expression

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Sun, 2 Oct 2022 02:14:04 -0400
On Sun, Oct 2, 2022 at 1:43 AM blacktea hamburger via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> I forgot to say that "behaves right" requires operator new to correspond to operator delete.
>
> If it corresponds, then the behavior is completely correct, because the delete expression is equivalent to call destructor + operator delete.
>
> Of course the code could be better:
>
> auto* p = operator new(sizeof(T));
> auto* pc = new(p) T;
> ::delete pc;

No, the better code would be either:

```
auto *pc = new T;
delete pc;
```

Or

```
auto *p = operator new(sizeof(T));
auto *pc = new(p) T;
pc->~T();
operator delete(p);
```

Why should anyone *want* to write what you wrote? The code is either
an over-complicated version of the first, or a confused version of the
second. Either way, there is no reason to ever write it.

The closest thing to a justification you've given for why it should be
OK is that it would reduce UB and UB is bad if it could instead be
made to (sometimes) work. I don't buy this.

UB is bad when it's *inconsistent*. Making it so that your
creation/allocation and destruction/deallocation have to match is
consistent. Making it so that inconsistent code sometimes works
doesn't make the language easier to learn. It just adds complexity in
the name of... what, exactly?

Besides "because I can", what exactly would possess a programmer to
sit down in front of their keyboard and write the code you've written?
The only reason I can think of is "because I forgot how I allocated
this memory/created this object".

That's not a good reason.

And note that the difference between your "better" and "subtly broken"
is forgetting a `::`.

That is a very good reason not to rely on this kind of nonsense.

The way you allocate storage/create objects should mirror how you
destroy objects/deallocate storage. That ought to be the rule; it's
simple and clear and easy to follow with exactly zero pitfalls. If C++
has something in it that says it's sometimes OK to violate that rule,
that isn't something that should be spread; it should be removed.

Can you give a reason why such a rule ought not be followed? Show me
actual good code that doesn't follow this rule. Not just code that
technically works because of some statement in the bowels of the
standard, but code that has some kind of advantage that is arguably
more important than having a simple rule everyone understands and can
easily follow.

Received on 2022-10-02 06:15:20