Are D classes proper reference types?

Ola Fosheim Grøstad ola.fosheim.grostad at gmail.com
Fri Jun 25 17:05:41 UTC 2021


On Friday, 25 June 2021 at 07:01:31 UTC, kinke wrote:
> Well AFAIK it's mandated by the language, so an RC scheme 
> replacing such allocations by heap ones seems like a definite 
> step backwards - it's a useful pattern, and as Stefan pointed 
> out, definitely in use. You could still stack-allocate but 
> accommodate for the counter prefix in the compiler.

Yes, but then I need to mark it as non-freeable.

> It's certainly possible as it's a library thing; some existing 
> code may assume the returned reference to point to the 
> beginning of the passed memory though (where there'd be your 
> counter). What you'd definitely need to adjust is 
> `__traits(classInstanceSize)`, accomodating for the extra 
> counter prefix.

Yes, if people don't make assumptions about where the class ends 
and overwrites some other object, but I suspect pointer 
arithmetics isn't all that common for classes in D code.

> There's very likely existing code out there which doesn't use 
> druntime's emplace[Initializer], but does it manually.

I guess, but the compiler could have a release note warning 
against this.

> ctor. It's probably easier to have the compiler put it into 
> static but writable memory, so that you can mess with the 
> counter.

Another reason to add the ability to mark it as non-freeable.

> All in all, I think a more interesting/feasible approach would 
> be abusing the monitor field of extern(D) classes for the 
> reference counter. It's the 2nd field (of pointer size) of each 
> class instance, directly after the vptr (pointer to vtable). I 
> think all monitor access goes through a druntime call, so you 
> could hook into there, disallowing any regular monitor access, 
> and put this (AFAIK, seldomly used) monitor field to some good 
> use.

Yes, if you don't want to support weak pointers. I think you need 
two counters if you want to enable the usage of weak pointers.

One reason to put it at a negative offset is that it makes it 
possible to make it fully compatible with shared_ptr. And then 
you can also have additional fields such as a weak counter or a 
deallocation function pointer.

I don't think maintaining the D ABI is important, so one could 
add additional fields to the class. Maintaining core language 
semantics shouldn't require ABI support I think.









More information about the Digitalmars-d-learn mailing list