Bug 12773 – Compiler implicitly converts delegate into function when taking an address of a method
Status
RESOLVED
Resolution
DUPLICATE
Severity
critical
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-05-20T09:27:00Z
Last change time
2014-12-31T06:45:45Z
Assigned to
nobody
Creator
andrej.mitrovich
Comments
Comment #0 by andrej.mitrovich — 2014-05-20T09:27:52Z
This is extremely nasty. Take a look:
-----
alias Func = void function();
class C
{
static void foo() { }
void bar() { }
}
void main()
{
{
// Func func = C.foo; // disallowed, since this is a function call
}
{
Func func = &C.foo; // ok, the proper syntax usage.
func(); // ok
}
{
Func func = &C.bar; // oops, we forgot to mark 'bar' as static!!
func(); // access violation (requires 'this')
}
}
-----
The current semantics force us to be extremely careful when using function pointers. We should ban the implicit conversion of &foo to a function pointer if this is really a non-static class method. People can use .funcPtr or some other equivalent instead.
Comment #1 by blah38621 — 2014-06-04T19:49:46Z
I suspect you meant to suggest removing the implicit conversion of &C.bar (a
delegate) to a function pointer. I would agree with this, and am extremely
surprised this is allowed in the first place. Perhaps it was an attempt to
implement implicit conversion from a function pointer to a delegate? (which
does make sense to be possible)
Comment #2 by nicolas.jinchereau — 2014-11-30T19:38:10Z
I believe this behaviour is by design. There is no implicit conversion, because &C.bar is not a delegate, it is a function pointer. The following code works as expected:
alias Func = void function();
alias Del = void delegate();
class C
{
string str = "bar";
static void foo() { }
void bar() { writeln(str); }
}
void main()
{
{
// Func func = C.foo; // disallowed, since this is a function call
}
{
Func func = &C.foo; // ok, the proper syntax usage.
func(); // ok
}
{
Func func = &C.bar; // correct
C c = new C;
Del del = &c.bar; // correct
Del del2;
del2.funcptr = func;
del2.ptr = cast(void*)c;
del2(); // works, output is "bar"
}
}
Comment #3 by yebblies — 2014-12-31T06:45:45Z
An old favorite.
*** This issue has been marked as a duplicate of issue 3720 ***