www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - need help to get member function const address

reply Calvin P <changlon gmail.com> writes:
I use this code to get member function address on runtime:

=========
struct A {
        this(){};
}
auto ctor = (&__traits(getMember, A.init,"__ctor")).funcptr;
=========


my question is, how to get it in compile time like static 
function address:

=========
struct A {
      void d(){};
      static void fn(){};
}

enum FN = &A.fn;  // static method address is ok
enum A0 = &(A.d).funcptr; // Error: need this for d of type void()
enum A1 = (&__traits(getMember, A,"d")).funcptr; // Error: no 
property funcptr for type void function()
enum A2 = (&__traits(getMember, A.init,"d")).funcptr; //  Error: 
(&A().d).funcptr cannot be evaluated at compile time
=========
Mar 14 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 3/14/20 5:06 AM, Calvin P wrote:
 I use this code to get member function address on runtime:
 
 =========
 struct A {
         this(){};
 }
 auto ctor = (&__traits(getMember, A.init,"__ctor")).funcptr;
 =========
 
 
 my question is, how to get it in compile time like static function address:
 
 =========
 struct A {
       void d(){};
       static void fn(){};
Note: no semicolons needed here
 }
 
 enum FN = &A.fn;  // static method address is ok
 enum A0 = &(A.d).funcptr; // Error: need this for d of type void()
enum A0 = &A.d; Note that you can't call it at all, but you can get the function pointer, and put it into a delegate later by assigning .funcptr. void main() { A a; void delegate() dg; dg.ptr = &a; dg.funcptr = A0; dg(); // calls a.d() } -Steve
Mar 16 2020
parent reply Calvin P <changlon gmail.com> writes:
On Monday, 16 March 2020 at 18:43:47 UTC, Steven Schveighoffer 
wrote:
 enum A0 = &A.d;

 Note that you can't call it at all, but you can get the 
 function pointer, and put it into a delegate later by assigning 
 .funcptr.

 void main()
 {
     A a;
     void delegate() dg;
     dg.ptr = &a;
     dg.funcptr = A0;
     dg(); // calls a.d()
 }

 -Steve
Thanks for the tips, Steve. I need to put them into a big const struct to use on runtime, so they can not be modify on runtime by mistake. I can not put the address into enum, because Error: need this to access d add cast(void*) still get same error: enum callee_ptr = cast(void*) &(__traits(getMember, A, "d")); // Error: need this to access d but I come up with a workaround: static void* getCallee() pure nogc nothrow { enum callee_ptr = &(__traits(getMember, App, name)); return callee_ptr; } __gshared const AppHelper APP_HELPER = {&getCallee, ..};
Mar 19 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 3/19/20 9:40 AM, Calvin P wrote:
 On Monday, 16 March 2020 at 18:43:47 UTC, Steven Schveighoffer wrote:
 enum A0 = &A.d;

 Note that you can't call it at all, but you can get the function 
 pointer, and put it into a delegate later by assigning .funcptr.

 void main()
 {
     A a;
     void delegate() dg;
     dg.ptr = &a;
     dg.funcptr = A0;
     dg(); // calls a.d()
 }
Thanks for the tips, Steve. I need to put them into a big const struct to use on runtime,  so they can not be modify on runtime by mistake. I can not put the address into enum,  because  Error: need this to access d add cast(void*) still get same error: enum callee_ptr = cast(void*) &(__traits(getMember, A, "d")); // Error: need this to access d but I come up with a workaround: static void* getCallee() pure nogc nothrow {         enum callee_ptr = &(__traits(getMember, App, name));         return callee_ptr; } __gshared const AppHelper  APP_HELPER = {&getCallee,  ..};
I'm not sure this is what you want. Essentially the address of the getCallee function is going to be put into AppHelper, so you are still fetching the function address at runtime. What might be best is simply to use a static ctor to build the struct you want (as long as it's not betterC): const AppHelper APP_HELPER; share static this() { APP_HELPER = ...; } It's kind of strange to me that you can't evaluate &A.d but you can evaluate &A.fn at compile time. Even stranger that it works as an enum, but not as a const function pointer. I too cannot find a way to make it work. I think this is an invalid limitation, you should file an issue at https://issues.dlang.org essentially, with your sample A struct: const f1 = &A.fn; // OK const f2 = &A.d; // Error, not constant expression Both these should be valid, &A.d is not a delegate, but a function pointer. -Steve
Mar 19 2020
parent reply Boris Carvajal <boris2.9 gmail.com> writes:
On Thursday, 19 March 2020 at 14:43:53 UTC, Steven Schveighoffer 
wrote:
 I think this is an invalid limitation, you should file an issue 
 at https://issues.dlang.org

 essentially, with your sample A struct:

 const f1 = &A.fn; // OK
 const f2 = &A.d; // Error, not constant expression

 Both these should be valid, &A.d is not a delegate, but a 
 function pointer.

 -Steve
https://issues.dlang.org/show_bug.cgi?id=20687 https://github.com/dlang/dmd/pull/10946
Mar 19 2020
parent Calvin P <changlon gmail.com> writes:
On Thursday, 19 March 2020 at 23:46:01 UTC, Boris Carvajal wrote:
 https://issues.dlang.org/show_bug.cgi?id=20687
 https://github.com/dlang/dmd/pull/10946
Thanks very much for such a quick fix.
Mar 20 2020