Jump to page: 1 2
Thread overview
[Issue 4838] New: Cannot declare a delegate variable for const member functions
Sep 07, 2010
klickverbot
Sep 08, 2010
klickverbot
Sep 08, 2010
Don
Sep 08, 2010
klickverbot
Sep 08, 2010
klickverbot
Sep 08, 2010
Don
Nov 27, 2011
Kenji Hara
May 11, 2012
SHOO
Oct 07, 2012
yebblies
September 07, 2010
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: -------
September 07, 2010
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: -------
September 08, 2010
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: -------
September 08, 2010
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: -------
September 08, 2010
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: -------
September 08, 2010
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: -------
September 08, 2010
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: -------
September 08, 2010
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: -------
November 27, 2011
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: -------
May 11, 2012
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: -------
« First   ‹ Prev
1 2