toString() through interface

David Held via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Apr 19 17:51:49 PDT 2014


On 4/19/2014 5:35 PM, David Held wrote:
> interface Foo { }
>
> class Bar : Foo
> {
>      override string toString() pure const { return "Bar"; }
> }
>
> void main()
> {
>      Foo foo = new Bar;
>      foo.toString();
> }

To make things more interesting, consider the call to toString() from 
inside a class (which is closer to my actual use case):

class Baz
{
     override string toString() pure const
     { return cast(Object)(foo).toString(); }

     Foo foo;
}

This really makes the compiler go bonkers:

src\Bug.d(11): Error: pure nested function 'toString' cannot access 
mutable data 'foo'
src\Bug.d(11): Error: pure nested function 'toString' cannot access 
mutable data 'foo'
src\Bug.d(11): Error: no property 'toString' for type 'Bug.Foo'
src\Bug.d(11): Error: pure nested function 'toString' cannot access 
mutable data 'foo'
src\Bug.d(11): Error: need 'this' for 'foo' of type 'Bug.Foo'

Apparently, DMD features "high-availability error reporting", because 
the first message might not be received by the programmer, so it writes 
it again, then gives you a different message, and writes it one more 
time, just in case there was a communication error or some other fault 
preventing you from receiving this important message about access to 'foo'.

Again, the cast appears to do absolutely nothing, as the compiler 
insists on looking up toString() in Foo instead of Object.  What is 
really peculiar is that message 1, 2, and 4 are complaining that 
Baz.toString() is not allowed to access foo because it is mutable.  And 
yet, the 5th error message tells us how to fix it: just add 'this.':

     override string toString() pure const
     { return cast(Object)(this.foo).toString(); }

Now we just get this:

src\Bug.d(11): Error: no property 'toString' for type 'const(Foo)'

Hmm...so adding 'this.' changes a field from "unacceptably mutable" to 
"just fine for this pure const method".  Isn't that weird?!?  Note also 
how the error message has subtly changed from "Bug.Foo" to "const(Foo)", 
because the compiler is still stubbornly insisting on ignoring the cast 
to 'Object'.  Is there a rational explanation for all this behavior??

Dave



More information about the Digitalmars-d-learn mailing list