I have a program like this:
type B = array[64, array[64, array[6, array[64, int32]]]]
const defaultB: B = block:
var r: B
...
r
func hi(i: int32): int32 =
defaultB[i][i][i div 10][i] * i
echo hi(9)
The problem I have, is that neither const defaultB: B = ... nor let defaultB: B = ... work because the stack size is too small. The best solution would probably be to just increase the stack size, is that something that I can do with Nim independently on the OS I am using?
What I also tried is to just mark the type B as a ref object. However, that requires the function hi to be marked as proc which I want to avoid. Is there a way to tell Nim, that a variable allocated on the heap should be immutable (not only the pointer, but also where the pointer is pointing to)?
i assume your type B is actually array[64,array[64,array[64,array[64,int32]]]] as 64*64*6*64 actually compiles and runs just fine (on linux anyway, with 8MB stack)
FIrst some bad answers:
to increase the stack you can try {.passL: "-z stack-size=67109864".} where the number is sizeof(B)+1000
i found that initializing a 64x64x64x64 array at compile time required --maxLoopIterationsVM:20000000 or so
or if you want to override the compiler's side-effect analysis and use a ptr or ref you could
let defaultBRef = block:
var r = new B
r[] = defaultB
r
#or let defaultBPtr = defaultB.unsafeAddr
func hi(i:int32):int32 =
{.cast(noSideEffect).}:
defaultBRef[i][i][i div 10][i] * i
putting your object on the heap isn't a bad idea, but why not pass it into hi as a parameter. it is still created at compile time but doesn't need to be copied into heap to be used, and it won't break the stack as it will certainly be passed as a hidden pointer:
import random#just making sure it's not optimized away
type B = array[64,array[64,array[64,array[64,int32]]]]
const defaultB:B = block:
var r:B
for i in 0'i32..63:
for j in 0'i32..63:
for k in 0'i32..63:
for l in 0'i32..63:
r[i][j][k][l] = i + j + k + l
r
func hiAux(b:B,i:int32):int32 =
b[i][i][i][i] * i
func hi(i:int32):int32 = defaultB.hiAux(i)
echo hi(rand(63).int32)
here's how:
func initB(res:var B) =
for i in 0'i32..63:
for j in 0'i32..63:
for k in 0'i32..63:
for l in 0'i32..63:
res[i][j][k][l] = i+j+k+l
func initB():B =initB(result)
let defaultB = initB()
func hi(d:B,i:int32):int32 = d[i][i][i][i]*i
when isMainModule:
import random
randomize()
echo defaultB.hi(rand(63).int32)
We do not have any support for this right now.
Is this something that might be possible in future versions?