Date: Sun, 22 Sep 2024 01:35:31 +0800
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?
best regards,
Julian
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?
best regards,
Julian
Received on 2024-09-21 17:36:08