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