www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 4838] New: Cannot declare a delegate variable for const member functions

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4838

           Summary: Cannot declare a delegate variable for const member
                    functions
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: major
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: code klickverbot.at


--- Comment #0 from klickverbot <code klickverbot.at> 2010-09-07 15:38:30 PDT
---
Given »class A { void foo() const {} }; A a = new A;«,
»typeof(&a.foo).stringof« yields »void delegate() const«.

However, trying to declare a delegate variable of this type like »void
delegate() const dg; dg = &a.foo;« fails with »const/immutable/shared/inout
attributes are only valid for non-static member functions« or, depending on the
scope one tries to declare the variable in, even more cryptic error messages.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 07 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4838


bearophile_hugs eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs eml.cc


--- Comment #1 from bearophile_hugs eml.cc 2010-09-07 16:33:20 PDT ---
Maybe you want to rewrite those code snippets into readable indented little
runnable programs.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 07 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4838



--- Comment #2 from klickverbot <code klickverbot.at> 2010-09-08 02:13:36 PDT
---
Okay, bearophile, here you go:

---
class A {
   void foo() const {}
}

void main() {
   A a = new A;

   pragma( msg, typeof( &a.foo ) ); // Yields »void delegate() const«
   void delegate() const dg = &a.foo; // Does not compile.
}
---

The error message for this simple case is »test.d(9):
const/immutable/shared/inout attributes are only valid for non-static member
functions
«.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 08 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4838


Don <clugdbug yahoo.com.au> changed:

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


--- Comment #3 from Don <clugdbug yahoo.com.au> 2010-09-08 02:21:14 PDT ---
(In reply to comment #2)
 Okay, bearophile, here you go:
 
 ---
 class A {
    void foo() const {}
 }
 
 void main() {
    A a = new A;
 
    pragma( msg, typeof( &a.foo ) ); // Yields »void delegate() const«
    void delegate() const dg = &a.foo; // Does not compile.
 }
 ---
 
 The error message for this simple case is »test.d(9):
 const/immutable/shared/inout attributes are only valid for non-static member
 functions
 «.
Change that last line to: const void delegate() dg = &a.foo; and it works. It's a parsing issue. I'm sure it's a dup of another bug. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 08 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4838



--- Comment #4 from klickverbot <code klickverbot.at> 2010-09-08 02:41:01 PDT
---
(In reply to comment #3)
 const void delegate() dg = &a.foo;
Would not that rather create a const(void delegate())? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 08 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4838


Steven Schveighoffer <schveiguy yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |schveiguy yahoo.com


--- Comment #5 from Steven Schveighoffer <schveiguy yahoo.com> 2010-09-08
06:25:16 PDT ---
Yes, it does:

import std.stdio;

class A
{
    void f() const {}
}

void main()
{
    A a = new A;
    auto g1 = &a.f;
    writefln("g1 = %s", typeof(g1).stringof);
    const void delegate() g2 = &a.f;
    writefln("g2 = %s", typeof(g2).stringof);
    void delegate() g3 = &a.f;
    writefln("g3 = %s", typeof(g3).stringof);
    g1();
    g2();
    g3();
}

compiles and outputs:

g1 = void delegate() const
g2 = const(void delegate())
g3 = void delegate()


It appears that you can remove the const decorations at will.  This is very not
good.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 08 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4838



--- Comment #6 from klickverbot <code klickverbot.at> 2010-09-08 06:26:46 PDT
---
(In reply to comment #5)
 It appears that you can remove the const decorations at will.  This is very not
 good.
See also: bug 1983. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 08 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4838



--- Comment #7 from Don <clugdbug yahoo.com.au> 2010-09-08 07:11:58 PDT ---
General comment: You have to be careful with .stringof, it's not yet reliable
(a difference in .stringof doesn't necessarily mean a difference in type). But
.mangleof never lies. The conclusion in this case is still correct, though.

A workaround for the original problem is to use auto (or typeof).

   pragma( msg, (&a.foo).mangleof );
   auto dg = &a.foo;                  // this works
   const void delegate() dg2 = &a.foo;
   pragma(msg, dg.mangleof);
   pragma(msg, dg2.mangleof);
-------
DxFZv
DxFZv
xDFZv

What I said still applies -- it's a parsing problem.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 08 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4838


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch


--- Comment #8 from Kenji Hara <k.hara.pg gmail.com> 2011-11-26 19:48:51 PST ---
https://github.com/D-Programming-Language/dmd/pull/539

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 26 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4838


SHOO <zan77137 nifty.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |zan77137 nifty.com


--- Comment #9 from SHOO <zan77137 nifty.com> 2012-05-11 03:09:41 PDT ---
This bug is very important for const/shared/immutable correctness.
The following code is caused by this issue clearly:

-------------------------
class A {
    int x;
    void foo() { x = 1; }
}

void bar(void delegate() dg) {
    dg();
}

void main() {
    immutable a = new immutable(A);
    assert(a.x == 0);
    bar(&a.foo);       // This line should be compilation error.
    assert(a.x == 0);  // core.exception.AssertError main(14): Assertion
failure
}
-------------------------

Its workaround is the following code:

-------------------------
class A {
    int x;
    void foo() { x = 1; }
}

alias typeof(&(new class(){void foo() const{}}).foo) void_delegate_const;
void bar(void_delegate_const dg) {
    dg();
}

void main() {
    immutable a = new immutable(A);
    assert(a.x == 0);
    bar(&a.foo);      // main.d(14): Error: function main.bar (void delegate()
const dg) is not callable using argument types (void delegate())
    assert(a.x == 0);
}
-------------------------

It is painful to write such correct code.
Fortunately, there is a PullRequest, so I hope to be merged as soon as
possible.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 11 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4838


yebblies <yebblies gmail.com> changed:

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


--- Comment #10 from yebblies <yebblies gmail.com> 2012-10-08 05:45:23 EST ---
https://github.com/D-Programming-Language/dmd/commit/ffca5f3f3e46bfb7dddc50b0e5bc2d8e4aba1088

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