How does D distnguish managed pointers from raw pointers?

rikki cattermole rikki at
Thu Oct 3 14:23:50 UTC 2019

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.

More information about the Digitalmars-d-learn mailing list