August 06, 2014
> This describes the semantics of regular arrays. Are you sure it also applies to AAs? I thought they will keep referring to the same data once they are initialized. But I might be mistaken...
>

This can be easily tested. And... you are right!

In the current implementation (I couldn't find any specification) the AA contains just a pointer[1]. I suppose that initially this pointer is null and on copy the pointer is copied, so that after initialization any change of the copy is visible in the original.

[1] https://github.com/D-Programming-Language/druntime/blob/master/src/rt/aaA.d#L82-85
August 07, 2014
On Wednesday, 6 August 2014 at 15:42:05 UTC, Marc Schütz wrote:
> On Wednesday, 6 August 2014 at 15:18:15 UTC, Dragos Carp wrote:
>> On Wednesday, 6 August 2014 at 14:36:23 UTC, Marc Schütz wrote:
>>>
>>> This would defeat the purpose, see the original post.
>>
>> sorry, I red just the last post.
>>
>> __gshared has no influence on this.
>
> Indeed, it was just what the OP suspected as the culprit.

You are right, I didn't know about the AA initialization problem then.

When I writln the AA and it outputs '[]', I thought it was initialized, which in that case was actually null.


>
>>
>>> auto cmds = CONFIG.commands;
>>> cmds["list"] = new Command(...);
>>
>> cmds is a thread local variable referencing the shared AA. But if you add new elements to cmds, cmd will be reallocated and the shared AA will remain unchanged. Though, updated values of existing keys will be visible in the original, because no relocation takes place.
>
> This describes the semantics of regular arrays. Are you sure it also applies to AAs? I thought they will keep referring to the same data once they are initialized. But I might be mistaken...
>
>>
>> If you want to change the original you need a pointer or a reference (for a setter function).
>>
>> auto cmds = &CONFIG.commands;
>> (*cmds)["list"] = new Command(...);

August 07, 2014
On Thu, Aug 07, 2014 at 02:00:27AM +0000, Puming via Digitalmars-d-learn wrote:
> On Wednesday, 6 August 2014 at 15:42:05 UTC, Marc Schütz wrote:
[...]
> >Indeed, it was just what the OP suspected as the culprit.
> 
> You are right, I didn't know about the AA initialization problem then.
> 
> When I writln the AA and it outputs '[]', I thought it was initialized, which in that case was actually null.
[...]

This is a known gotcha with AA's and built-in arrays: they are null until you insert something into them, which means that while they are null, passing them into functions that add stuff to them won't update the original references because there is no common object that null points to. But once they become non-empty, passing them around to functions that change their contents will affect what's seen through the original references, since now they are pointing at a common object in memory.  So they behave like value types when null, but acquire reference semantics once they are non-empty. This can be rather confusing for newbies.


T

-- 
Ignorance is bliss... until you suffer the consequences!
August 07, 2014
Indeed it's confusing.

So AA is a value type that behaves like a pointer/reference.

We can add a rule to the initialization to make AA behave more like reference types:

If someone `refer` to an unitialized AA, that is, by doing:

```d
string[string] aa;

string[string] bb = aa; // bb `refers` to aa, by actually copying the AA struct.
```

They must want to use bb the same as aa, and it mostly will be followed by an assignment to bb (otherwise why bother refering it?). So we can initialize the AA BEFORE copying the struct, similar to the process before assigning an unitialized AA.

Actually, I think ANY structs that mimics a reference behavior should add this rule to really look like a reference.


On Thursday, 7 August 2014 at 02:17:19 UTC, H. S. Teoh via Digitalmars-d-learn wrote:
> On Thu, Aug 07, 2014 at 02:00:27AM +0000, Puming via Digitalmars-d-learn wrote:
>> On Wednesday, 6 August 2014 at 15:42:05 UTC, Marc Schütz wrote:
> [...]
>> >Indeed, it was just what the OP suspected as the culprit.
>> 
>> You are right, I didn't know about the AA initialization problem then.
>> 
>> When I writln the AA and it outputs '[]', I thought it was
>> initialized, which in that case was actually null.
> [...]
>
> This is a known gotcha with AA's and built-in arrays: they are null
> until you insert something into them, which means that while they are
> null, passing them into functions that add stuff to them won't update
> the original references because there is no common object that null
> points to. But once they become non-empty, passing them around to
> functions that change their contents will affect what's seen through the
> original references, since now they are pointing at a common object in
> memory.  So they behave like value types when null, but acquire
> reference semantics once they are non-empty. This can be rather
> confusing for newbies.
>
>
> T

August 07, 2014
It's an optimization of memory allocation: you can always have a usable AA without allocating anything for it, so when you fill it with data, you may want to assign it back to where it should stay, similar to a slice.
August 07, 2014
Yes indeed, null initial value is reasonable. My suggestion does not affect that rationale, but is only based on my observation that if someone want to `refer` to an AA, he is more likely to fill it very soon, and he really mean to refer to it. These are similar concerns:

- create a null AA, then fill it, and the compiler/runtime will automatically initialize it before the fill.

- create a null AA, then refer to it (and would then use it), and the compiler/runtime wil automatically initialize it before the refer.


On Thursday, 7 August 2014 at 11:05:33 UTC, Kagamin wrote:
> It's an optimization of memory allocation: you can always have a usable AA without allocating anything for it, so when you fill it with data, you may want to assign it back to where it should stay, similar to a slice.

1 2
Next ›   Last »