On Friday, 11 January 2013 at 08:26:54 UTC, Jonathan M Davis wrote:
On Friday, January 11, 2013 08:53:44 Don wrote:
Consider this code:
---
    int[int] x;

    int k = x[2] + 5; // Error, range violation. Makes sense.

    x[2] = x[2] + 5;  // But this works!!!
---

That is, x[2] doesn't exist, *unless you are about to assign to
it*.

What happens is:
1. lvalue index (creates x[2], sets it to int.init)
2. rvalue index (returns x[2], which is now 0)
3. lvalue index assign (sets x[2] = 5)

In reality, step 1 returns a pointer to the newly created element.

How could this be implemented as a library type?
The superficially similar case, x[2] += 5; can be implemented
with opIndexOpAssign. But I don't know how to do this one.

Note that elements are not always magically created when an
lvalue is required. AFAIK it only happens in assignment. For
example this code gives a runtime error:
---
void foo(ref int g) { ++g; }

    int[int] x;
    foo( x[2] );  // range error, x[2] doesn't exist yet
---

I would argue that the fact that

x[2] = x[2] + 5;

works is a bug.

I completely agree. Doesn't the spec say that relying on
the order of assignment evaluation is undefined?

Reply via email to