Strage class' with invariant() {} function behaviour

Jarrett Billingsley jarrett.billingsley at gmail.com
Wed Oct 8 11:52:09 PDT 2008


On Wed, Oct 8, 2008 at 2:34 PM, mumba <qniol at o2.pl> wrote:
> Hello people.
>
> Check this out, and explain please.
>
> class Foo {
>    invariant(Object) bar() {
>        return new invariant(Object); //return sth caller cannot change
>    }
> }
>
> So far, so good. Now:
>
> class Foo {
>    invariant() {} //some design by contract stuff, nothing related to type's storage classes
>    Object bar() { //less restrictive version of the previous func
>        return new Object;
>    }
> }
>
> So far so good. Now let's make a fusion:
>
> class Foo {
>    invariant() {}
>    invariant(Object) bar() {
>        return new invariant(Object);
>    }
> }
>
> BANG! (dmd v2.014)
> variable test.Foo.bar.__result cannot modify invariant
>
> ...
>
> Of course, I have some theories, but I wouldn't come here if they were good, so I'll keep them for myself. Tell me yours.
>
> cheers.
>

D's contracts allow you to put an out contract on a function to see
what the result of the function was:

void foo()
out(result) { /* check that result is reasonable */ }
body { /* function body */ }

When you declare a class invariant, it calls the invariant after each
public method is called.  My guess is that D is inserting an implicit
"out(result) { assert(this); }" on each public method, but the out
contract probably hasn't yet been updated and thinks typeof(result) is
just Object, not invariant(Object).  Hence, error.

It's most likely a bug.


More information about the Digitalmars-d-learn mailing list