8

I tried the following

struct mbuf
{
  cacheline: *mut [u64],               // great amount of rows follows below
  // ..........
}
static mut arr: [mbuf; 32];                // Q1 my main aim
// something as before but using Vec;      // Q2 also main aim

fn main() {
 // let static mut arr: [mbuf; 32];        // Q3 also doesn't work
 // static mut arr: [mbuf; 32];            // Q3 also doesn't work
}

and got error

src/main.rs:74:29: 74:30 error: expected one of `+` or `=`, found `;`
src/main.rs:74   static mut arr: [mbuf; 32];
                                           ^

Q1,Q2,Q3 - Is it possible and how?

2
  • 2
    Well surely you want to use the variables, and surely you don't want to leave them uninitialized. So what do you want? Commented May 9, 2015 at 23:24
  • I want to initialize and work with such variables in main. I rewrite С application to check it's speed in rust. So I need to have similar architecture design. Also I am beginner in rust :) Commented May 10, 2015 at 8:09

2 Answers 2

9

A static or constant must be assigned when declared; they can never be assigned to after that.

A static must be purely literals; it cannot have any function calls.

A constant must at present be purely literals, but when RFC 911, const fn is implemented it will be possible to do things more like how you desire.

Inside a function, you can have static or const items, just as outside a function, and there is no difference—placing items (trait and type definitions, functions, &c.) inside a function purely hides them from the outside scope. Therefore you typically might as well use let foo.

Sign up to request clarification or add additional context in comments.

1 Comment

static variables can be mutable although they need to be marked unsafe. rustbyexample.com/custom_types/constants.html says "static: A possibly mutable variable with 'static lifetime."
8

You can use lazy-static to initialize the static array on first access, even though it might incur a minimal overhead (it seems to invoke Once::call_once every time you access the static variable).

For example, Cargo.toml:

[package]
name = "arr"
version = "0.0.1"

[[bin]]
name = "arr"
path = "arr.rs"

[dependencies]
lazy_static = "*"

arr.rs:

#[macro_use]
extern crate lazy_static;
use std::mem;
use std::ptr;

#[derive(Debug)]
struct Mbuf {
    cacheline: *mut u64,
}
// Let's pretend it's thread-safe to appease the lazy_static! constrains.
unsafe impl Sync for Mbuf { }

lazy_static! {
    static ref ARR: [Mbuf; 32] = {
        let mut tmp: [Mbuf; 32] =  = unsafe { mem::MaybeUninit::uninit().assume_init() };
        for idx in 0..tmp.len() {
            tmp[idx] = Mbuf { cacheline: ptr::null_mut() };
        }
        tmp
    };
}

fn main() {
    println!("{:?}", *ARR);
}

Alternatively, just make your own lazy accessor:

use std::mem;
use std::ptr;

#[derive(Debug)]
struct Mbuf {
    cacheline: *mut u64,
}

static mut ARR: Option<[Mbuf; 32]> = None;
fn arr() -> &'static mut [Mbuf; 32] {
    unsafe {
        if ARR.is_none() {
            let mut tmp: [Mbuf; 32] = mem::MaybeUninit::uninit().assume_init();
            for idx in 0..tmp.len() {
                tmp[idx] = Mbuf { cacheline: ptr::null_mut() };
            }
            ARR = Some(tmp);
        }
        mem::transmute(ARR.as_mut().unwrap())
    }
}

fn main() {
    println!("{:?}", arr());
}

Needless to say, this code isn't thread-safe and thus shuns some of the Rust safety guarantees, but for a speed comparison port it shall suffice.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.