D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 12773 - Compiler implicitly converts delegate into function when taking an address of a method
Summary: Compiler implicitly converts delegate into function when taking an address of...
Status: RESOLVED DUPLICATE of issue 3720
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P1 critical
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-05-20 09:27 UTC by Andrej Mitrovic
Modified: 2014-12-31 06:45 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Andrej Mitrovic 2014-05-20 09:27:52 UTC
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 Orvid King 2014-06-04 19:49:46 UTC
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 forsaken 2014-11-30 19:38:10 UTC
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 yebblies 2014-12-31 06:45:45 UTC
An old favorite.

*** This issue has been marked as a duplicate of issue 3720 ***