arrays of const, postblit and RefCounted

monarch_dodra monarchdodra at gmail.com
Thu Nov 29 07:14:50 PST 2012


I investigating some weird behavior regarding arrays of const 
object. I'm not 100% sure what I'm observing, but it would appear 
that when adding objects to a const array, objects are not 
postblit-ed? Is this the expected behavior?

In this program, "S" is a struct that just prints when postblit 
is called:
//----
void main()
{
     S[] arr;
     foreach (i; 0 .. 5)
     {
         writeln(i);
         arr ~= S(i);
     }
}
//----
0
post
1
post
2
post
3
post
post
post
post
4
post
//----
Here, we can clearly see each element being postblit inserted. We 
can also see the array re-locating.

However, if we change "S[] arr;" to "const(S)[] arr;", then the 
output becomes:
//----
0
1
2
3
4
//----

Strange... right?

I was actually investigating the issue when trying to do a const 
array of refcounted. It was behaving scary weird...:

//----
alias RCI = RefCounted!(int, RefCountedAutoInitialize.no);
void main()
{
     const(RCI)[] arr;
     foreach (i; 0 .. 3)
     {
         foreach (j; 0 .. i)
             writefln("pay[%s]: %s", j, arr[j].refCountedPayload);

         auto a = const(RCI)(i);
         writefln("declared a: %s", a.refCountedPayload);

         foreach (j; 0 .. i)
             writefln("pay[%s] before: %s", j, 
arr[j].refCountedPayload);

         arr ~= a;

         foreach (j; 0 .. i + 1)
             writefln("pay[%s] after: %s", j, 
arr[j].refCountedPayload);
         writeln();
     }
     writeln("after");
     foreach (i; 0 .. 3)
         writeln("pay: ", arr[i].refCountedPayload);
}
//----
declared a: 0
pay[0] after: 0

pay[0]: 0
declared a: 1
pay[0] before: 1
pay[0] after: 1
pay[1] after: 1

pay[0]: 0
pay[1]: 0
declared a: 2
pay[0] before: 2
pay[1] before: 2
pay[0] after: 2
pay[1] after: 2
pay[2] after: 2

after
pay: 0
pay: 0
pay: 0
//----

See!?

The sole fact of declaring a on the stack modifies the values of 
all the elements in the array... And as soon as it goes out of 
scope, they all become 0 :/

The weirdest part (IMO), is that since "RefCountedAutoInitialize 
== no", the value "0" is not a result of an auto initialize: It 
is the actual allocated value of the RCI that is changing...

Changing it to non const "fixes" this, but I really don't even 
begin to fathom what is happening...

Thoughts?


More information about the Digitalmars-d mailing list