Thread overview
member pointers
Mar 13, 2007
bc
Mar 13, 2007
Daniel Keep
Mar 13, 2007
Frits van Bommel
Mar 13, 2007
Kirk McDonald
March 13, 2007
am i being stupid or is there any chance of adding pointers to member functions and pointers to data members to D? i can't see any way of getting the same functionality through existing language constructs for member functions... alias seems like it might at first but i can't get it to work... and the offsetof syntax for data members seems buggy. otherwise, congrats on designing a really cool language
March 13, 2007
bc wrote:
> 
> am i being stupid or is there any chance of adding pointers to member functions and pointers to data members to D? i can't see any way of getting the same functionality through existing language constructs for member functions... alias seems like it might at first but i can't get it to work... and the offsetof syntax for data members seems buggy. otherwise, congrats on designing a really cool language

Let's see...

> import std.stdio;
>
> class Foo
> {
>     uint xzzxy = 0;
>
>     void bar()
>     {
>         writefln("Bar, bar, member func, have you any Foo?");
>         writefln("The magic number is: %d", this.xzzxy);
>     }
> }
>
> alias void delegate() voiddg; // <-- just for shorthand
>
> void main()
> {
>     Foo baz = new Foo;
>
>     uint* quxxy = &baz.xzzxy; // <-- pointer to an attribute
>     *quxxy = 42;
>
>     voiddg dg = &baz.bar; // <-- "pointer" to our member function
>     dg();
> }

Delegates are your pointer to member functions.  Pointers to data of an object are just as you would expect.  Or did you have a different use in mind?

	-- Daniel

-- 
Unlike Knuth, I have neither proven or tried the above; it may not even make sense.

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
March 13, 2007
Daniel Keep wrote:
> bc wrote:
>> am i being stupid or is there any chance of adding pointers to member
>> functions and pointers to data members to D? i can't see any way of
>> getting the same functionality through existing language constructs for
>> member functions... alias seems like it might at first but i can't get
>> it to work... and the offsetof syntax for data members seems buggy.
>> otherwise, congrats on designing a really cool language
> 
[snip code]
> 
> Delegates are your pointer to member functions.  Pointers to data of an
> object are just as you would expect.  Or did you have a different use in
> mind?

In C++, a "pointer to member" is a pointer to a _class_ member, not an _instance_ member. That pointer can then be combined with an instance and dereference to the member of that class. If the pointer is to a virtual function, calling the function pointed to will call the correct override for that instance. (the pointer type is a combination of type of the class and the type of the member)
So there are basically three cases:
* pointer to data member: equivalent to typed offset into object
* virtual function: equivalent to typed offset into vtable
* non-virtual function: equivalent to function pointer (but still requires "this" pointer)

As far as I know, D has no direct equivalent to this, though pointers to data members could probably be trivially written as a template struct.
One complication with member function pointers is that the latter two cases above must both fit into the same type (so a pointer to a member function must be able to reference both virtual and non-virtual functions).
The compiler could probably easily implement this though. One way to make this easier to implement would be to give non-virtual functions vtable offsets as well, so the pointer can be just an offset into the vtable instead of a struct or "tagged union" type of thing. That way they can also remain the same size as a size_t.
Note: pointers to member functions can be up to 16 bytes in some popular C++ compilers, though C++ does need to handle a few case that D doesn't like multiple inheritance and classes that have only been forward-declared, as well as classes that aren't allowed to contain a vtable pointer)
March 13, 2007
Frits van Bommel wrote:
> Daniel Keep wrote:
>> bc wrote:
>>> am i being stupid or is there any chance of adding pointers to member
>>> functions and pointers to data members to D? i can't see any way of
>>> getting the same functionality through existing language constructs for
>>> member functions... alias seems like it might at first but i can't get
>>> it to work... and the offsetof syntax for data members seems buggy.
>>> otherwise, congrats on designing a really cool language
>>
> [snip code]
>>
>> Delegates are your pointer to member functions.  Pointers to data of an
>> object are just as you would expect.  Or did you have a different use in
>> mind?
> 
> In C++, a "pointer to member" is a pointer to a _class_ member, not an _instance_ member. That pointer can then be combined with an instance and dereference to the member of that class. If the pointer is to a virtual function, calling the function pointed to will call the correct override for that instance. (the pointer type is a combination of type of the class and the type of the member)
> So there are basically three cases:
> * pointer to data member: equivalent to typed offset into object
> * virtual function: equivalent to typed offset into vtable
> * non-virtual function: equivalent to function pointer (but still requires "this" pointer)
> 
> As far as I know, D has no direct equivalent to this, though pointers to data members could probably be trivially written as a template struct.
> One complication with member function pointers is that the latter two cases above must both fit into the same type (so a pointer to a member function must be able to reference both virtual and non-virtual functions).
> The compiler could probably easily implement this though. One way to make this easier to implement would be to give non-virtual functions vtable offsets as well, so the pointer can be just an offset into the vtable instead of a struct or "tagged union" type of thing. That way they can also remain the same size as a size_t.
> Note: pointers to member functions can be up to 16 bytes in some popular C++ compilers, though C++ does need to handle a few case that D doesn't like multiple inheritance and classes that have only been forward-declared, as well as classes that aren't allowed to contain a vtable pointer)

It is interesting to note that Pyd exploits D's behavior w.r.t. pointers to virtual member functions to implement its class wrapping. That is, given a base class and a derived class:

class Base {
    void foo() {}
}

class Derived : Base {
    void foo() {}
}

You can call Base.foo on an instance of Derived.foo with some delegate trickery:

void delegate() dg;
dg.ptr = new Derived;
dg.funcptr = &Base.foo;
dg();

The reasons Pyd needs to do this are fairly complex, and I don't feel like explaining them in this space. Suffice to say, it's a good reason, and certain parts of Pyd's class wrapping implementation would be even more complex without it.

To perhaps put minds at ease, I will say that the context in which it does this is fairly well guaranteed to be safe. (The derived class is generated by Pyd, so I can be pretty sure it's not doing anything to blow this up.)

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org