Evaluation order of index expressions

Timon Gehr via Digitalmars-d digitalmars-d at puremagic.com
Sun May 24 14:18:53 PDT 2015


On 05/24/2015 10:35 PM, Jonathan M Davis wrote:
> On Sunday, 24 May 2015 at 20:30:00 UTC, Timon Gehr wrote:
>> On 05/24/2015 09:48 PM, Jonathan M Davis wrote:
>>> 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?
>>
>> Because this is not C.
>>
>> BTW, the documentation contradicts itself on evaluation order:
>> http://dlang.org/expression.html
>
> There have been discussions on defining the order of evaluation from
> left-to-right such that it may happen, but there have been issues raised
> with it as well (particularly from an optimization standpoint, though
> IIRC, it causes some havoc for the gdc folks as well given how the gcc
> backend works).
> ...

Optimizations can reorder operations when the compiler is able to prove 
equivalence, and there actually are annotations to help. Yes, 
occasionally, reorderings that the compiler won't be able to do on its 
own might lead to non-trivial performance improvements. In such cases, 
do them manually. The gcc backend obviously supports ordered operations, 
because some operations are ordered today.

> Regardless, having an expression where you're mutating a variable and
> using either it or something that depends on it within the same
> expression is just plain bug-prone,

So what? If such a bug occurs, you want to be the one who sees it, not 
the guy who tries to use your code with a different compiler.

> and even if the compiler wants to
> makes all such cases a compilation error, it's trivial to move some of
> the changes into a function call and hide it such that the compiler
> can't catch it.

'pure','const',... Even then, the compiler should not want to make all 
such cases a compilation error; it is not necessary if evaluation order 
is defined.

> So, the reality of the matter is that even if we get
> more restrictive about the order of evaluation in expressions, we can't
> actually prevent the programmer from shooting themselves in the foot due
> to issues with the order of evaluation.

We can at least go as far as to not artificially add additional 
foot-shooting failure modes to the weapon.

> At most, we can reduce the
> problem, but that just pushes it from common, relatively easy to catch
> cases, to more complex ones, so on some level, it's simply providing a
> false sense of security.
>...

No. Seriously. Under the current semantics, running an exhaustive 
input-output test on a fully @safe program will not ensure that the code 
is actually correct. Talk about providing a false sense of security.



More information about the Digitalmars-d mailing list