Thread overview
how to initialize immutable 2 dim array
Oct 31, 2010
Michal Minich
Oct 31, 2010
Stewart Gordon
Oct 31, 2010
Michal Minich
Oct 31, 2010
bearophile
Oct 31, 2010
Michal Minich
Oct 31, 2010
Michal Minich
Oct 31, 2010
bearophile
Oct 31, 2010
bearophile
Oct 31, 2010
Michal Minich
October 31, 2010
I have global static array and I want it to initialize in module constructor, but I get error. I there way to do it without using enum.

immutable int[5][5] arr;

static this () {
   arr = new int[5][5]; // Error: slice arr[] is not mutable
}
October 31, 2010
On 31/10/2010 17:10, Michal Minich wrote:
> I have global static array and I want it to initialize in module
> constructor, but I get error. I there way to do it without using enum.

So you want to initialise it with data acquired at runtime, but make it immutable once initialised?

> immutable int[5][5] arr;
>
> static this () {
>     arr = new int[5][5]; // Error: slice arr[] is not mutable
> }

You have a more fundamental problem here.  arr is a static array, so you can't reference-assign it.

Best you can do is to either:

- initialise it statically, using CTFE or template metaprogramming to do the calculations, if they don't depend on getting external data

- use a dynamic array instead, and use .idup to populate it

- create a mutable pointer to it in the module constructor
    int[5][5]* marr = cast(int[5][5]*) arr;
and use that to populate the array.  But I'm not sure whether this leads to UB, and I still wish the means of casting away const or immutable were explicit.

Stewart.
October 31, 2010
On Sun, 31 Oct 2010 17:46:29 +0000, Stewart Gordon wrote:

> On 31/10/2010 17:10, Michal Minich wrote:
>> I have global static array and I want it to initialize in module constructor, but I get error. I there way to do it without using enum.
> 
> So you want to initialise it with data acquired at runtime, but make it immutable once initialised?
> 
>> immutable int[5][5] arr;
>>
>> static this () {
>>     arr = new int[5][5]; // Error: slice arr[] is not mutable
>> }
> 
> You have a more fundamental problem here.  arr is a static array, so you can't reference-assign it.
> 
> Best you can do is to either:
> 
> - initialise it statically, using CTFE or template metaprogramming to do the calculations, if they don't depend on getting external data
> 
> - use a dynamic array instead, and use .idup to populate it
> 
> - create a mutable pointer to it in the module constructor
>      int[5][5]* marr = cast(int[5][5]*) arr;
> and use that to populate the array.  But I'm not sure whether this leads
> to UB, and I still wish the means of casting away const or immutable
> were explicit.
> 
> Stewart.

I would rather use CTFE, but seems it isn't possible to work with 2 dim arrays at compile time. Also I need it to be static array, otherwise i would need to rewrite and test more code. I like the simple workaround with using mutable pointer, but I'm getting access violation error even when arr is mutable ... and really don't understand why... :(

int[256][256] arr;

static this () {

    int[256][256]* pArr = &arr;

    for (int y = 0; y <= 255; y++)
        for (int x = 0; x <= 255; x++)
            pArr[x][y] = x * y; // Access violation when x = 2 and y = 0
}
October 31, 2010
Michal Minich:

> I like the simple workaround with using mutable pointer, but I'm getting access violation error even when arr is mutable ... and really don't understand why... :(
> 
> int[256][256] arr;
> 
> static this () {
> 
>     int[256][256]* pArr = &arr;
> 
>     for (int y = 0; y <= 255; y++)
>         for (int x = 0; x <= 255; x++)
>             pArr[x][y] = x * y; // Access violation when x = 2 and y = 0
> }

You need to put a bit more thought on your code:

import std.stdio: writeln;

int[256][256] arr;

static this () {
    auto pArr = &arr;
    foreach (y; 0 .. (*pArr)[0].length)
        foreach (x; 0 .. (*pArr).length)
            (*pArr)[x][y] = x * y;
}

void main() {
    writeln(arr);
}

(I have just fixed your code locally, I don't know what you are doing and why you are using a pointer to a fixed sized array, it's an unusual idiom in D.)

Bye,
bearophile
October 31, 2010
On Sun, 31 Oct 2010 14:53:42 -0400, bearophile wrote:

> import std.stdio: writeln;
> 
> int[256][256] arr;
> 
> static this () {
>     auto pArr = &arr;
>     foreach (y; 0 .. (*pArr)[0].length)
>         foreach (x; 0 .. (*pArr).length)
>             (*pArr)[x][y] = x * y;
> }
> 
> void main() {
>     writeln(arr);
> }
> 
> (I have just fixed your code locally, I don't know what you are doing and why you are using a pointer to a fixed sized array, it's an unusual idiom in D.)
> 
> Bye,
> bearophile

(*pArr)[x][y] = .. fixes it!

Thank you!

I need to use this workaround because global array I want to initialize in module constructor is immutable.
October 31, 2010
On Sun, 31 Oct 2010 19:13:33 +0000, Michal Minich wrote:

>>     foreach (y; 0 .. (*pArr)[0].length)

also good tip on the foreach syntax, it is much cooler :)

is there some performance overhead compared to using for (int x = 0; x <= 255; x++) ?
October 31, 2010
Michal Minich:

> I need to use this workaround because global array I want to initialize in module constructor is immutable.

A pointer to a immutable array is immutable. So you aren't improving the code, just making it more obfuscated. So there is zero need to use a pointer.

Immutable data is not meant to be modified, a compiler may move your empty array in read only memory. This is bad.

Some people have recently discussed about this problem and a bug report was proposed. Until some language-supported solution is found, the simpler solution for this problem may be to use a static mutable array...


> is there some performance overhead compared to using for (int x = 0; x <= 255; x++) ?

In theory there is no difference. In practice there is no difference with dmd only if you use the -O compiler switch. So it's a compiler implementation thing, and you need to look at the produced asm if you want to be sure with a different compiler.

Bye,
bearophile
October 31, 2010
> Some people have recently discussed about this problem and a bug report was proposed. Until some language-supported solution is found, the simpler solution for this problem may be to use a static mutable array...

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


October 31, 2010
On Sun, 31 Oct 2010 17:21:50 -0400, bearophile wrote:

>> Some people have recently discussed about this problem and a bug report was proposed. Until some language-supported solution is found, the simpler solution for this problem may be to use a static mutable array...
> 
> http://d.puremagic.com/issues/show_bug.cgi?id=5147

Thank you for the bug report. Voted.