Generate a pointer to a method of a struct

kdevel kdevel at vogtner.de
Fri Oct 14 18:34:58 UTC 2022


Given a struct `S` with method `foo`: Any of these expressions
```
    &foo
    &S.foo
    &.S.foo
```
when they occur inside the struct they represent a delegate and 
not a function pointer. Is it okay to "extract" and use the 
function pointer from the delegate in this way:

```
struct S {
    void function () fp;
    void foo ()
    {
       fp = (&bar).funcptr;
    }
    void bar ()
    {
       fp = (&foo).funcptr;
    }
    auto fun () // invocation helper
    {
       if (! fp)
          fp = (&foo).funcptr;
       void delegate () dg;
       dg.ptr = &this;
       dg.funcptr = fp;
       return dg ();
    }
}

unittest {
    S s;
    s.fun;
    s.fun;
}
```

In [1] Walter suggested to use a "lambda function" which reads 
(adopted to structs):

```
struct S {
    :
    void function (ref S) fp;
    :
    void foo () {
       :
       fun = function (ref S self) { return self.bar (); };
       :
    }
    :
}
```

dmd and gdc optimize the lambda invocations away. Nonetheless the 
expression looks somewhat too big. To overcome this I tried to 
generate the function pointer outside of the struct:

```
auto funcptr (alias method) ()
{
    return &method;
}
       :
       fun = funcptr!bar;
       :
```

Which works but neither dmd nor gdc were able to optimize the 
additional function call away. So I replaced the function call 
with a value:

```
template funcptr (alias method) {
    immutable funcptr = &method; // (*)
}
```

That code compiles under gdc 12.1 but I could not find any dmd 
version which compiles the code. All say

```
ptrtomethod.d(15): Error: non-constant expression `& bar`
```

Line 15 is the line I marked with `(*)`. Any comments?

[1] https://www.digitalmars.com/articles/b68.html
     Member Function Pointers in D


More information about the Digitalmars-d-learn mailing list