Thread overview
Immutable array initialization in shared static this
Jul 13, 2012
Tommi
Jul 13, 2012
Jonathan M Davis
Jul 13, 2012
Matej Nanut
Jul 13, 2012
Minas Mina
Jul 13, 2012
Era Scarecrow
Jul 13, 2012
Ali Çehreli
Jul 14, 2012
Tommi
Jul 16, 2012
Tommi
July 13, 2012
The following code doesn't compile. It seems like a compiler bug to me, but I can't find a bug report about it. Is it a bug?

private immutable(int[]) constants;

shared static this()
{
    constants.length = 10;
    constants[0] = 123; // Error: constants[0] isn't mutable
}
July 13, 2012
On Friday, July 13, 2012 12:15:33 Tommi wrote:
> The following code doesn't compile. It seems like a compiler bug to me, but I can't find a bug report about it. Is it a bug?
> 
> private immutable(int[]) constants;
> 
> shared static this()
> {
>      constants.length = 10;
>      constants[0] = 123; // Error: constants[0] isn't mutable
> }

It's not a bug. You have to initialize the entire array at once, since it's immutable. By setting the length, you initialized the array such that it had 10 elements in it all of which were the init value of the element type (which would be 0, since it's int). If you don't want to use an array litera like

constants = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

then create a mutable array which you then either idup and assign it to constants, or you cast it to immutable (or use std.exception.assumeUnique, which casts to immutable but is used to document the fact it is the only reference to that data and therefore safe to cast to immutable) and then assign it to constants.

- Jonathan M Davis
July 13, 2012
I'm not sure, but it seems like it.

You can do

        constants ~= 123;

or

        constants = [ 123 ];

just fine.

There could be a reason behind this, but if you're allowed to change the array anyway, you should probably be able to change it in any way you like.
July 13, 2012
I guess it's because you have an array of constants (immutables). The array is not immutable though. I could be wrong, I'm not an expert or D syntax :)
July 13, 2012
 When you use the length property it allocates space and assigns it to the immutable array. the array now contains data (10 0's). You've said you won't change any data in it's declaration but the array itself can be changed (appending or a different array).

 I would think the best solution is to create a mutable local version, and then assign the immutable global one when you are done. If the array is particularly short (Like your example), then appending will work fine for your values (unless you mutate the array as part of it's calculation, then a local copy is required).
July 13, 2012
On 07/13/2012 11:09 AM, Era Scarecrow wrote:

> I would think the best solution is to create a mutable local version,
> and then assign the immutable global one when you are done.

And there wouldn't be a copy with std.exception.assumeUnique:

import std.exception;

private immutable(int[]) constants;

shared static this()
{
    int[] local;
    local.length = 10;
    local[0] = 123;
    constants = assumeUnique(local);
}

void main()
{
    assert(constants[0] == 123);
}

Ali

-- 
D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html

July 14, 2012
On Friday, 13 July 2012 at 18:09:59 UTC, Era Scarecrow wrote:
>  I would think the best solution is to create a mutable local version, and then assign the immutable global one when you are done.

Thanks for the workaround. But I'm actually more interested in whether or not this is a compiler bug or not, so that I could file a bug report. The following code makes me more certain that this in fact is a bug. Because in some sense there shouldn't be much difference between int and a fixed size int array of size 1:

module main;

import std.stdio;

immutable(int)    value;
immutable(int[1]) staticArray;

shared static this()
{
    value = 123;          // OK
    staticArray[0] = 123; // Error: staticArray[0] isn't mutable
}

int main(string args[])
{
    writeln(value);
    readln();
    return 0;
}


July 16, 2012
Hmm.. actually, it seems there have been plenty of reports of this issue already. Didn't see it the first time:

http://d.puremagic.com/issues/show_bug.cgi?id=6174