Thread overview
How to get address of a nested function?
Nov 10, 2020
Max Samukha
Nov 10, 2020
Max Samukha
Nov 10, 2020
Daniel Kozak
Nov 10, 2020
Daniel Kozak
Nov 11, 2020
Max Samukha
November 10, 2020
We can get the compile time equivalent of a member function's address by applying '&' to the function in a static context:

struct S {
    void foo() {}
}

enum pfoo = &S.foo; // ok

void main() {
    // now we can use the pointer to create, for example, a delegate
    S s;
    void delegate() dg;
    dg.ptr = &s;
    dg.funcptr = pfoo;
    dg();
}

However, we can't do that to a nested function:

void main() {
    void foo() {
    }
    enum pfoo = &foo; // weird kind of an enum delegate; pfoo.funcptr can't be accessed at compile time.
}

Is there a way to get a pointer to a non-static nested function?
November 10, 2020
On 11/10/20 5:51 AM, Max Samukha wrote:
> We can get the compile time equivalent of a member function's address by applying '&' to the function in a static context:
> 
> struct S {
>      void foo() {}
> }
> 
> enum pfoo = &S.foo; // ok
> 
> void main() {
>      // now we can use the pointer to create, for example, a delegate
>      S s;
>      void delegate() dg;
>      dg.ptr = &s;
>      dg.funcptr = pfoo;
>      dg();
> }
> 
> However, we can't do that to a nested function:
> 
> void main() {
>      void foo() {
>      }
>      enum pfoo = &foo; // weird kind of an enum delegate; pfoo.funcptr can't be accessed at compile time.
> }
> 
> Is there a way to get a pointer to a non-static nested function?

I don't think you can do it at compile time. You can at runtime by accessing the funcptr of the delegate.

-Steve
November 10, 2020
On Tuesday, 10 November 2020 at 14:36:04 UTC, Steven Schveighoffer wrote:

>> 
>> Is there a way to get a pointer to a non-static nested function?
>
> I don't think you can do it at compile time. You can at runtime by accessing the funcptr of the delegate.
>
> -Steve

Thanks for the reply. I will post the issue to bugzilla.
November 10, 2020
On Tue, Nov 10, 2020 at 8:50 PM Max Samukha via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote:

> On Tuesday, 10 November 2020 at 14:36:04 UTC, Steven Schveighoffer wrote:
>
> >>
> >> Is there a way to get a pointer to a non-static nested function?
> >
> > I don't think you can do it at compile time. You can at runtime by accessing the funcptr of the delegate.
> >
> > -Steve
>
> Thanks for the reply. I will post the issue to bugzilla.
>

Why?
It works for me

import std.stdio;
void main() {
    void foo() {
        writeln("It works as expected");
    }
    enum pfoo = &foo;

    void delegate() dg = pfoo;
    dg();

}


November 10, 2020
On Tue, Nov 10, 2020 at 11:55 AM Max Samukha via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote:

> We can get the compile time equivalent of a member function's address by applying '&' to the function in a static context:
>
> struct S {
>      void foo() {}
> }
>
> enum pfoo = &S.foo; // ok
>
> void main() {
>      // now we can use the pointer to create, for example, a
> delegate
>      S s;
>      void delegate() dg;
>      dg.ptr = &s;
>      dg.funcptr = pfoo;
>      dg();
> }
>
> However, we can't do that to a nested function:
>
> void main() {
>      void foo() {
>      }
>      enum pfoo = &foo; // weird kind of an enum delegate;
> pfoo.funcptr can't be accessed at compile time.
> }
>
> Is there a way to get a pointer to a non-static nested function?
>

non static nested function is a delegate, so you can just assign it to delegate like I have posted or you can du this:

import std.stdio;
void main() {
    void foo() {
        writeln("It works as expected");
    }
    enum pfoo = &foo;

    void delegate() dg;
    dg.ptr = pfoo.ptr;
    dg.funcptr = pfoo.funcptr;
    dg();
}


November 11, 2020
On Tuesday, 10 November 2020 at 20:13:30 UTC, Daniel Kozak wrote:

>
> non static nested function is a delegate, so you can just assign it to delegate like I have posted or you can du this:
>
> import std.stdio;
> void main() {
>     void foo() {
>         writeln("It works as expected");
>     }
>     enum pfoo = &foo;
>
>     void delegate() dg;
>     dg.ptr = pfoo.ptr;
>     dg.funcptr = pfoo.funcptr;
>     dg();
> }

I need the funcptr at *compile time*, just as I can do "enum p = &S.foo" for a non-static member function.

I wrote "weird" not because '&' returns a delegate, but because I was surprised that we can have enum delegates at all, given that delegates carry a context pointer, which is not known at compile time. That is, the enum delegate appears to be some kind of alias of the '&' expression.

Not that the issue is critical, but it makes a library I am writing incomplete.