D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3939 - Built-in __vptr attribute for classes too
Summary: Built-in __vptr attribute for classes too
Status: RESOLVED WONTFIX
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-03-12 13:33 UTC by bearophile_hugs
Modified: 2018-05-17 07:29 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2010-03-12 13:33:25 UTC
The attribute __vptr of object instances can be useful in some special situations. To compare the __vptr of an object instance to the __vptr of a class you first need to find the __vptr of a class. You can do it with code similar to:


class Foo {
    __gshared static immutable(immutable(void)*) __vptr;
    static this() {
        scope auto aux = new typeof(this);
        __vptr = aux.__vptr;
    }
    //...
}
void main() {}


But this is not handy (even if a class mixin can help). So a built-in __vptr attribute can be added to classes too.

Possible disadvantages: the need for __vptr is rare.

-------------

Note: there are other ways to implement virtual functions, like using a dispatch tree, so the D docs can say that __vptr can be absent in D compilers that don't use a virtual table or in other situations.
Comment 1 bearophile_hugs 2010-10-24 18:27:12 UTC
Currently this seems the most efficient way to have a static class attribute that contains a __vptr (here converted to a size_t and named classId):


class Foo {
    static immutable size_t classId;
    static this() {
        classId = *(cast(size_t*)(typeid(Foo).init.ptr));
    }
}
void main() {
    assert(cast(size_t)((new Foo).__vptr) == Foo.classId);
}


With it DMD 2.049 generates a very light static constructor:


_D4test3Foo12_staticCtor1FZv	comdat
		mov	EAX,_D4test3Foo7__ClassZ[0Ch]
		mov	ECX,[EAX]
		mov	_D4test3Foo7classIdyk,ECX
		ret
Comment 2 Dmitry Olshansky 2018-05-17 07:29:11 UTC
Could be taken from typeinfo, see object.d:

class TypeInfo_Class : TypeInfo
{
...
   void*[]     vtbl;           /// virtual function pointer table
   Interface[] interfaces;     /// interfaces this class implements
...
}

So I believe those who truly need it will find it. And solution provided is actually fine for such low-level goal.