D - more invariant fun
- Patrick Down (63/63) Dec 22 2002 I've run into another interesting problem with the invariant
- Walter (6/61) Dec 31 2002 The invariant test is done only on public member functions, the end of
I've run into another interesting problem with the invariant
section. Let's say I have the following setup.
import random;
class Foo
{
void changeState()
{
if(a)
a = 0;
else
a = rand()+1;
}
invariant
{
assert(a >= 0);
}
int a;
}
class Bar : Foo
{
void changeState()
{
super.changeState();
if(a)
b = rand();
else
b = 0;
}
int b;
invariant
{
assert((a && b) || !(a || b));
}
}
int main(char[][] argv)
{
Bar c = new Bar();
c.changeState();
return 0;
}
Now this code will generate an assertion failure from Bar's
invariant section. The problem is that Bar's changeState()
will leave the object in a correct state according to the
test in the invariant section. However, the call to
super.changeState() in Bar.changeState() calls the invariant
section also. After this call the object is in a transition
state that is invalid so the invariant section generates an
assertion failure.
Now I am of the opinion that calls from a member function to
another member function of the same class should not be subject
to an invariant test. However I can see implementation issues
with this.
Another interesting point of note is that if Foo's invariant
section is removed then this program will no longer generate
an assertion failure.
Dec 22 2002
The invariant test is done only on public member functions, the end of
constructors, and the beginning of the destructor. The solution to the
problem below is to make a protected function changeState() in the base
class. -Walter
"Patrick Down" <pat codemoon.com> wrote in message
news:Xns92ECD79FE127Epatcodemooncom 63.105.9.61...
I've run into another interesting problem with the invariant
section. Let's say I have the following setup.
import random;
class Foo
{
void changeState()
{
if(a)
a = 0;
else
a = rand()+1;
}
invariant
{
assert(a >= 0);
}
int a;
}
class Bar : Foo
{
void changeState()
{
super.changeState();
if(a)
b = rand();
else
b = 0;
}
int b;
invariant
{
assert((a && b) || !(a || b));
}
}
int main(char[][] argv)
{
Bar c = new Bar();
c.changeState();
return 0;
}
Now this code will generate an assertion failure from Bar's
invariant section. The problem is that Bar's changeState()
will leave the object in a correct state according to the
test in the invariant section. However, the call to
super.changeState() in Bar.changeState() calls the invariant
section also. After this call the object is in a transition
state that is invalid so the invariant section generates an
assertion failure.
Now I am of the opinion that calls from a member function to
another member function of the same class should not be subject
to an invariant test. However I can see implementation issues
with this.
Another interesting point of note is that if Foo's invariant
section is removed then this program will no longer generate
an assertion failure.
Dec 31 2002








"Walter" <walter digitalmars.com>