Thread overview
[Issue 5328] New: The addressof-expression that should be rejected is accepted
Dec 06, 2010
Haruki Shigemori
Dec 06, 2010
nfxjfg@gmail.com
Dec 07, 2010
Don
Jun 19, 2011
yebblies
December 06, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5328

           Summary: The addressof-expression that should be rejected is
                    accepted
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: accepts-invalid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: rayerd.wiz@gmail.com


--- Comment #0 from Haruki Shigemori <rayerd.wiz@gmail.com> 2010-12-06 08:56:21 PST ---
// a.d
void f(void function() m) { m(); }

class A
{
    this()
    {
        f(&A.m); // rejects-invalid => OK
    }

    /+static+/ void m() {}
}

void main()
{
    f(&A.m); // accepts-invalid => BAD!!
}

$ dmd a.d
a.d(7): Error: function a.f (void function() m) is not callable using argument
types (void delegate())
a.d(7): Error: cannot implicitly convert expression (&this.A.m) of type void
delegate() to void function()

You will get the following result if you remove A.this constructor.

$ dmd a.d
object.Error: Access Violation

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 06, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5328


nfxjfg@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |nfxjfg@gmail.com
            Version|D2                          |D1 & D2
         OS/Version|Windows                     |All


--- Comment #1 from nfxjfg@gmail.com 2010-12-06 09:21:27 PST ---
It's a feature, not a bug. You can take the address of methods without providing an object reference (i.e. no this pointer, or what would be the context member of method delegates).

The returned function pointer is simply what the class' vtable contains. The function signature is the same as the signature of a proper delegate to the method. It doesn't make sense to call the function pointer by itself (wrong calling convention, this pointer is missing), but it's useful for other things.

E.g. you can use the type of the function pointer value in meta programming to get the method's signature. That's very important for meta programming. You could just instantiate a new object, and then analyze the delegate, but why should you need to construct a dummy object? For the actual value of the function pointer there are also valid uses. Think about serialization of delegates, for example.

Note that the delegate property .funcptr return a similarly non-sensical function pointer. The context is missing and the calling convention is incompatible. If you call it, you get an access violation as well.

What is happening here is that the language "designers" just didn't feel like introducing a dedicated separate function type for this purpose. Instead, they reused the "normal" function pointer type, even if calling it makes no sense. Basically it's a quick language hack that endangers type-safety and confuses users.

Btw. the code inside A.this is not accepted, because the "A." from "&A.m" just qualifies the member "m". Inside the ctor it's exactly the same as writing "&m". And &m is a delegate, not a function. So everything is alright. Though this slight syntactic ambiguity is another hint that D as a language is actually quite unorthogonal and full of special cases. Maybe "&typeof(this).m" in the ctor would do the same as the &A.m in main()?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 07, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5328


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug@yahoo.com.au


--- Comment #2 from Don <clugdbug@yahoo.com.au> 2010-12-06 23:35:07 PST ---
(In reply to comment #1)
> It's a feature, not a bug. You can take the address of methods without providing an object reference (i.e. no this pointer, or what would be the context member of method delegates).


> What is happening here is that the language "designers" just didn't feel like introducing a dedicated separate function type for this purpose. Instead, they reused the "normal" function pointer type, even if calling it makes no sense. Basically it's a quick language hack that endangers type-safety and confuses users.

Are you sure this is an intentional design decision, and not just an oversight? Was it discussed by Walter and Andrei in the newsgroup?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 19, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5328


yebblies <yebblies@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |yebblies@gmail.com
         Resolution|                            |DUPLICATE


--- Comment #3 from yebblies <yebblies@gmail.com> 2011-06-18 23:35:49 PDT ---
*** This issue has been marked as a duplicate of issue 3720 ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------