rust-lang-nursery / lazy-static.rs

A small macro for defining lazy evaluated static variables in Rust.
Apache License 2.0
1.9k stars 108 forks source link

Unexpected stack overflow when initializing array #205

Open camilchp opened 1 year ago

camilchp commented 1 year ago

The following code generates a stack overflow, despite containing no explicitly recursive code.

extern crate lazy_static; // 1.4.0

use lazy_static::lazy_static;

const SIZE : usize = 1_000_000;
const U0 : usize = 0;

fn u_gen() -> [usize;SIZE] {

        let mut u = [U0;SIZE];
        for i in 1..SIZE {
            u[i] = (u[i-1] + 1) % 10;
        } 
        u
}

lazy_static! {
    static ref U : [usize;SIZE] = u_gen();
}

fn main() {
    dbg!((*U)[0]);
    //dbg!(u_gen()[0]);
}

playground link On my laptop, the stack overflow occurs in Debug mode, but not in Release mode.

On the playground, on the other hand, I get a stack overflow in both modes.

The problem only occurs when u_gen is called in lazy_static. When calling it directly (see commented line in main), everything goes fine.

cc @pchampin

JosuGZ commented 1 year ago

That is a big array to be on the stack. I'm experiencing the same problem with a smaller one though (80Kb).

I'm not sure if lazy_static boxes the value but before that I think it creates it on the stack, and it makes copies of it.

pchampin commented 1 year ago

Agreed, such a big array on the stack may not be ideal. But the fact that it works without lazy_static and fails with it makes it a bug, regardless.