function pointer bug?

bitwise via Digitalmars-d digitalmars-d at puremagic.com
Wed Oct 29 13:24:40 PDT 2014


I think I've got it figured out.

In my original example, I added the following line inside the 
function-template, and the class-template:

pragma(msg, typeof(T).stringof);

in both cases, the (correct)result was a tuple of a function 
(void())

But, when it came time to retrieve the address of the function, 
the behaviour was not the same inside the scope of the function, 
and the class.

this line behaved differently in both cases:

dg.funcptr = &T[0];

inside the function-template, the above line worked correctly, 
and the function's address was taken. However, inside the 
class-template, the compiler attempted to call T[0] which yielded 
this error:

Error: this for instanceMethod needs to be type TestClass not 
type main.FuncPtr!(instanceMethod).FuncPtr

So, at this point, I saw that the compiler was not parsing things 
in a consistent way, and came up with this template:

template addressOf(T...) {
     enum addressOf = &T[0];
}

Finally, my example worked as expected after making this change:

dg.funcptr = &T[0];
to
dg.funcptr = addressOf!(T[0]);


Onward..

Given that my current project is a reflection library, I 
proceeded to start swapping in __traits.

All of these worked correctly (class methods):

invokeFunction!(__traits(getMember, TestClass, 
"instanceMethod"))(cast(void*)testClass);
invokeFunction!(__traits(getMember, TestClass, 
"staticMethod"))(null);
auto fp1 = new FuncPtr!(__traits(getMember, TestClass, 
"instanceMethod"));
auto fp2 = new FuncPtr!(__traits(getMember, TestClass, 
"staticMethod"));

But these did not(global methods).

invokeFunction!(__traits(getMember, thisModule, 
"GlobalMethod"))(null);
auto fp3 = new FuncPtr!(__traits(getMember, thisModule, 
"GlobalMethod"));

Both of the above lines failed with the following error:

Error: function main.GlobalMethod () is not callable using 
argument types (void)



So finally, I would describe these bugs as follows:

1) the addressOf(T...) template should not be needed inside the 
class-template. Both cases in the original post should behave 
consistently. The problem is inconsistent handling of template 
arguments between function templates and class templates.

2) the return of __traits(getMember) is not treated the same way 
as the symbol itself when parsed. In the case of GlobalMethod, 
the compiler tries to call the method when it's returned from a 
__trait, but does not when it's referenced directly.

Does anyone concur with these diagnoses?

And is there any way in D to explicitly request that a function 
not be called without parens?



More information about the Digitalmars-d mailing list