C++ Logo

std-discussion

Advanced search

Making the new expression smart

From: Farid Mehrabi <farid.mehrabi_at_[hidden]>
Date: Thu, 17 Sep 2020 13:56:28 +0430
I have been tossing this idea in my mind for almost 20 years. The current
schema of overloading operator new belongs to dinosaur era IMO.
If we could provide operator new with the requested type - instead of just
its size (and optionally alignment), then the return type could also be a
custom allocator (rather just void*). This in turn would enable the new
expression to return a smart pointer - rather than a dangerous raw pointer:

smart_allocator operator new(compiler_provided_params,user_provided_params)
value_type { /*...*/};

The corresponding new expression:

auto ptr=new(user_provided_args) value_type {initializer_args};
Would then generate pseudo code sequence like this:

auto ptr = [&}(){
    smart_allocator temp_alloc{ operator
new(compiler_provided_args,user_provided_args) value_type };
    smart_pointer ret=temp_alloc(initializer_args);
   return std::move(ret);
}();

The exact type and number of compiler provided parameters is open to
discussion, but it must at least provide the following functionality:

auto constructor_lambda(compiler_provided_params){
    return [](void * void_this, auto && ... initializer){
        ::new(__none_overloadable_placement__ , void_this) value_type
 {std::forward<decltype(initializer)>(initializer) ... };
    };
};

the multi-lambda in the above pseudo snippet shall correspond to all
accessible overloads of constructors of value_type in the context of
calling new-expression. other functionality such as destructor
accessibility and assignment operator overload set may also be considered,
but avialablity of accessible constructors is of prime essence IMHO.
This proposition is aiming at encouraging the *usage of raw pointers as
observer-only* idiom. I am trying to combine the syntax clarity of *new* with
safety of *make_smart *family of convenience functions. Other benefits
include:

   - passing the whole type - instead of just its size - to the *operator
   new* enables safely conveying meta-data about exact type of object to
   runtime such as *clonabilty *true destructor. One problem with
   traditional *new-expression* is destructor slicing of none-polymorphic
   hierarcies (that this proposition can help avoid):

std::unique_ptr<base> { new derived };// dtor is sliced if base does not
declare it as virtual

smarter_unique_ptr<base> { new(smart_tag) derived }; // can avoid
destructor slicing if uses smart overloading for new


   - Custom return type of *new *enables optimizing data structure of smart
   pointers; e.g it is possible to embed the count of references into the same
   block of allocation as the actual object, enabling superfast reference
   counting.
   - Prohibit lots of issues (double-delete, dangling ptr, memory leak ...)
   resulting from improper pointer initialization.


Regards,
FM.

Received on 2020-09-17 04:27:09