Pure Contract bug?

David Held dmd at wyntrmute.com
Thu Jan 2 16:20:37 PST 2014


On 2/4/2012 2:04 PM, Era Scarecrow wrote:
> [...]
> struct X {
>     int i;
>     pure int squaredPlus(int x) {
>         return x*x + i
>     }
>     alias squaredPlus sqp;
> }
>
>     X st(15);
>
>     writeln(st.sqp(0));  //15
>     int i1 = st.sqp(10); st.i++;
>     int i2 = st.sqp(10); st.i++;
>     int i3 = st.sqp(10); st.i++;
>     int i4 = st.sqp(10); st.i++;

You can rewrite these like so:

int i1 = sqp(st, 10); st.i++;
int i2 = sqp(st, 10); st.i++;
int i3 = sqp(st, 10); st.i++;
int i4 = sqp(st, 10);

At this point it becomes a little more obvious that these cannot be 
reordered because their arguments have a shared dependency, just like 
the following cannot be reordered:

int i = 15;
int i1 = i * i; ++i;
int i2 = i * i; ++i;
int i3 = i * i; ++i;
int i4 = i * i;

I hope we all agree that opMult(int, int) is pure, and that is both safe 
to reorder its execution with non-dependent args, and unsafe to do so here.

>     assert(i1 == 100); //pass/fail?
 > [...]

Fail.  It should be i1 == 115. ;)

Dave



More information about the Digitalmars-d-learn mailing list