On 04/10/2019 3:13 AM, IGotD- wrote:
According to the GC documentation this code snippet

char* p = new char[10];
char* q = p + 6; // ok
q = p + 11;      // error: undefined behavior
q = p - 1;       // error: undefined behavior

suggests that char *p is really a "fat pointer" with size information.

The pointer is raw.
There is no size information stored with it.

The GC will store size information separately from it so it can know about reallocation and what its memory range is to search for.

However, if get some memory allocated by some C library that is allocated with malloc we have no size information. We would get a char * without any size information and according to the documentation we can do anything including access out of bounds.

Access out of bounds is do-able with a pointer allocated by the GC.

int[] array;
arr.length = 5;

int* arrayPointer = array.ptr;
int value = arrayPointer[10]; // compiles!!! but will segfault at runtime

And of course that won't work in @safe code.

How does D internally know that a pointer was previously allocated by the GC or malloc?

Either the GC has that information or it doesn't.

If we would replace the GC with reference counting. How would D be able to distinguish a reference counted pointer from a raw pointer at compile time in order to insert the code associated with the reference counting?

It can't.

This brings me back to MS managed C++ where they actually had two types of "pointers" a managed pointer and the normal C++ pointers. Like this:

MyType^ instance = gcnew MyType();

In this case it was obvious what is done with GC and what wasn't (past tense since managed C++ is deprecated). In this case it would be trivial to replace the GC algorithm with whatever you want since the compiler know the type at compile time.

There is only one type of pointer in D.

The GC is a library with language hooks. Nothing more than that.
It is easily swappable from within druntime.

But it does need to hook into threads and control them (e.g. thread local storage and pausing them) so there are a few restrictions like it must be chosen immediately after libc initialization at the start of druntime initialization.

Reply via email to