Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
October 31, 2010 how to initialize immutable 2 dim array | ||||
---|---|---|---|---|
| ||||
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 Re: how to initialize immutable 2 dim array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michal Minich | 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 Re: how to initialize immutable 2 dim array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stewart Gordon | 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 Re: how to initialize immutable 2 dim array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michal Minich | 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 Re: how to initialize immutable 2 dim array | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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 Re: how to initialize immutable 2 dim array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michal Minich | 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 Re: how to initialize immutable 2 dim array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michal Minich | 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 Re: how to initialize immutable 2 dim array | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > 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 Re: how to initialize immutable 2 dim array | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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.
|
Copyright © 1999-2021 by the D Language Foundation