When should `const` be used within a function?

I understand the value of const outside of functions because they can be inlined, but when should const values be used within a function scope?

I was writing some code and trying to take the approach of using the most restrictive type possible (thankfully Rust has awesome defaults here), so I began to declare variable bindings as const probably influenced by C++ background where that keyword is also used for immutablity.

But const has the downside that types cannot be inferred, consider:

fn main() {
    const NUMBERS: [i32; 5] = [1, 2, 3, 4, 5];
    let numbers = [1, 2, 3, 4, 5];

    const X: u32 =  5;
    let x = 5;
}

After making several large arrays similar to NUMBERS above (and wondering why the size couldn't be inferred), I asked myself the question "Why aren't I just using immutable bindings?" (like numbers).

So I'm curious, what (if any) are the tradeoffs between function-scoped consts compared to immutable bindings? Are there times to use one over the other? I feel it's unlikely, but can function-scoped const's be optimized more than immutable bindings?

3 Likes

These may be helpful:

https://doc.rust-lang.org/book/variable-bindings.html
https://doc.rust-lang.org/book/const-and-static.html
constants - What is the difference between immutable and const variables in Rust? - Stack Overflow

The short version is a let variable can go out of scope and be freed, and a const remains in memory for the entirety of the program.

To give some concrete example, consider

fn foo() {
    let xs: [u8; 1024] = include_bytes!("some stuff");
}

fn bar() {
    const xs: [u8; 1024] = include_bytes!("some stuff");
}

I am almost sure that the actual byte array will be in read only data segment of the executable, but what about the stack space required for foo and bar? Will every call to foo allocate 1kb on stack? What tools can I use to find that out?

1 Like

I don't believe this will leak, and that each pass through a function or loop will ultimately refer to the same constant.

Playpen link

It appears that both arrays are stored in the executable, but foo copies it onto the stack before using it.

When should const be used within a function?

My personal answer is to use it every time you can...

1 Like