www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Very confusing error message when calling a class method from an

reply Meta <jared771 gmail.com> writes:
class Human {
     static immutable MAX_AGE = 122;

     bool alive = true;
     int age = 0;
     //Error: mutable method onlineapp.Human.checkAge is not 
callable using a const object
     invariant(checkAge());

     void growOlder()
     in(alive)
     out(; checkAge())
     {
         age++;
         if (age > MAX_AGE)
             die();
     }

     void die()
     in(alive)
     out(; !alive) {
         alive = false;
     }

     bool checkAge() {
         return age >= 0 && age <= MAX_AGE || !alive;
     }
}

void main() {
     Human h = new Human();
     h.growOlder();
}

What the hell does this even mean, and where does it come from? 
Adding `inout` to `checkAge` actually does cause it to compile 
and run too. WTF?
Mar 09 2021
parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 10 March 2021 at 03:39:15 UTC, Meta wrote:
 class Human {
     static immutable MAX_AGE = 122;

     bool alive = true;
     int age = 0;
     //Error: mutable method onlineapp.Human.checkAge is not 
 callable using a const object
     invariant(checkAge());
[...]
 What the hell does this even mean, and where does it come from? 
 Adding `inout` to `checkAge` actually does cause it to compile 
 and run too. WTF?
From the language spec [1]:
 The invariant is in the form of a const member function.
So, inside the invariant, the object is treated as const, which means you can't modify it and can only call const methods. [1] https://dlang.org/spec/class.html#invariants
Mar 09 2021
parent Meta <jared771 gmail.com> writes:
On Wednesday, 10 March 2021 at 04:57:19 UTC, Paul Backus wrote:
 On Wednesday, 10 March 2021 at 03:39:15 UTC, Meta wrote:
 class Human {
     static immutable MAX_AGE = 122;

     bool alive = true;
     int age = 0;
     //Error: mutable method onlineapp.Human.checkAge is not 
 callable using a const object
     invariant(checkAge());
[...]
 What the hell does this even mean, and where does it come 
 from? Adding `inout` to `checkAge` actually does cause it to 
 compile and run too. WTF?
From the language spec [1]:
 The invariant is in the form of a const member function.
So, inside the invariant, the object is treated as const, which means you can't modify it and can only call const methods. [1] https://dlang.org/spec/class.html#invariants
Now that you mention it, I'm pretty sure I've run into this before; I must've forgotten about it. I understand the rationale behind this, but it doesn't really make sense IMO that only invariants treat the object as const, and not pre/post conditions as well. Ah well. Thanks for quick answer.
Mar 09 2021