This actually is not a proposal, I don't even know how to implement it. But we can discuss it.
I'm always thinking a pointer that directly created by new is different from by other meanings.
A * ptr = new A();
Here we can ensure that this ptr is safer than which's retrieved by following syntax,
A* ptr = &a;
or
A* ptr = &(ptrB->a); which *ptrB is the structure contains A a;
or
A* a = &a_vector[0]; here a_vector is vector<A>
The ptr directly created by new can be treated as an object's handler. And in most cases this ptr will be valid until you call delete ptr manually or by gc_count to 0 (in shared_ptr).
Actually in some cases, we should only accept that type of ptr. E.g. in shared_ptr<A>( A* ptr); (this example even hope you write new A() inside the parenthesis )
But the problem is how to track that information during runtime.
1. We might use a new keyword "safe" or "unsafe" when creating that ptr (e.g. safe A * ptr = new A() ), but it requires all functions and structs use the safe syntax to accept the safe ptr even for old libs, otherwise the "safe" information will be lost after passing to the functions and structures.
2. We could provide safe_cast<>() to convert an unknown safe ptr to safe ptr with runtime check. So that for a ptr is safe or unsafe we need runtime support.
3. We could provide static_safe_cast<>() for an unknown safe ptr to a safe ptr, without runtime check.
4. How to treat A* ptr1 = new A() and A* ptr2 = new A[100]{} , do we treat ptr2 as safe or not?
5. char * bytes = new char [sizeof(A)]; safe A * ptr = new (bytes) A{} should be forbidden because replace new is unsafe, you will only get unsafe A * ptr = new(bytes) A{}. I'm wondering we should make crash directly if you do so. The only correct way is
void * bytes = malloc(sizeof(A) ); A* ptr = new (bytes) A{}
6. struct A{B firstVar;}; A * ptr = new A(); B * ptr2 = reinterpret_cast<B*>(ptr); safe B* ptrB = dynamic_safe_cast<B*>(ptr2). We should get null even if ptr2 is actual B * type.
7. in delete ptr; C runtime should check if the ptr is of safe type A. (If with some compile flag)
I think it will be useful especially when someone want to provide a gc manager in c++ language.