Evaluation order of index expressions

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Sun May 24 12:48:04 PDT 2015


On Sunday, 24 May 2015 at 19:30:54 UTC, kinke wrote:
> <code>
> import core.stdc.stdio;
>
> static int[] _array = [ 0, 1, 2, 3 ];
>
> int[] array() @property { printf("array()\n"); return _array; }
> int   start() @property { printf("start()\n"); return 0; }
> int   end()   @property { printf("end()\n");   return 1; }
>
> void main()
> {
>     array[start..end] = 666;
>     printf("---\n");
>     array[start] = end;
> }
> </code>
>
> <stdout>
> array()
> start()
> end()
> ---
> start()
> array()
> end()
> </stdout>
>
> So for the 2nd assignment's left-hand-side, the index is 
> evaluated before evaluating the container! Please don't tell me 
> that's by design. :>
>
> [origin: 
> https://github.com/D-Programming-Language/phobos/pull/3311]

Why would you expect the order to even be defined? There's no 
operator precedence involved, so the compiler is free to order 
the evaluations however it likes.

And code like was originally in the PR is just plain error-prone. 
It's like doing

foo(++i, ++i);

only worse, because the fact that array is a property and count 
is used inside it is not immediately obvious when looking at

array[count++] = 666;

The original code is clearly wrong. And forcing the order of 
evaluation so that it's one way or the other just changes under 
which cases you end up with bugs. Mutating in an expression while 
using it multiple times in that expression or mutating a variable 
in an expression while using a variable that depends on it is 
just plain error-prone and is a serious code smell.

I really don't see anything wrong with what the compiler is doing 
in this case. The problem is that the code was making bad 
assumptions.

- Jonathan M Davis


More information about the Digitalmars-d mailing list