C++ Logo

std-proposals

Advanced search

Re: [std-proposals] It seems impossible to use new on a class with a deleted operator delete

From: Magnus Fromreide <magfr_at_[hidden]>
Date: Sun, 22 Sep 2024 00:38:14 +0200
On Sun, Sep 22, 2024 at 01:35:31AM +0800, Julian Waters via Std-Proposals wrote:
> Hi all,
>
> I just noticed a strange thing in the language. If one deletes operator
> delete for a specific class, it becomes entirely impossible to create an
> object instance of that class with new expressions if exception handling is
> enabled and one is using a conforming compiler, since new expressions call
> operator delete to deallocate allocated memory if an exception is
> encountered. Nothing can be used to bypass this oddity in the language,
> from marking constructors and every method called in them as noexcept, to
> using LTO to allow the compiler to discern whether the constructor ever
> throws or not, for the simple reason that "the operator delete function is
> named by the new expression, regardless of whether the initialization can
> throw". This effectively means you cannot delete operator delete ever if
> you want to create an object instance of that class using new, unless you
> use language extensions, turn off exception handling entirely for C++, or
> otherwise use a non conforming compiler, which would pretty much mean
> you're not using C++, but one of many dialects of it. There are many usages
> of deleted operator delete, with one example off the top of my head being
> custom memory allocators in the HotSpot Java Virtual Machine (
> https://github.com/openjdk/jdk/blob/2461263aac35b25e2a48b6fc84da49e4b553dbc3/src/hotspot/share/memory/allocation.hpp#L391),
> so this seems like a strange limitation to me, is this intended or an
> oversight?

This all depends on how twisted your mind is as operator new and
operator delete only handles memory allocation and deallocation.

--- test.cpp ---
#include <new>

struct s {
        void operator delete(void*) = delete;
};

char buf[sizeof(s)];

int main()
{
        s* sp = new(static_cast<void*>(buf)) s;

        sp->~s();
}
--- end of test.cpp ---

I chose to just use a static area for my s here but one could obviously put
the data area on the heap as well.

/MF

Received on 2024-09-21 22:38:20