More magical AA semantics

Jonathan M Davis jmdavisProg at gmx.com
Fri Jan 11 00:25:59 PST 2013


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. Given some of the weirdness that happens with assigning to AA 
elements, it doesn't entirely surprise me. For instance,

x[2] = funcThatThrows();

results in x[2] holding the init value of x's element type. But I think that 
it's indicative of problems with the current AA implementation which need to 
be fixed and not something that we should be trying to emulate with library 
types.

- Jonathan M Davis


More information about the Digitalmars-d mailing list