4 ms·
You can use your own allocator in Rust, with your own rules, OR you can use static arrays and then just reset aray length to zero at the end of frame. Your fun
by drran 5y ago
You can use your own allocator in Rust, with your own rules, OR you can use static arrays and then just reset aray length to zero at the end of frame.
Your function is easy to write in (unsafe!) Rust:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=cf7ca3a63d846130e4ff0602e5af34d7 https://play.rust-lang.org/?version=stable&mode=debug&editio...
use lazy_static::lazy_static; // 1.4.0
use std::mem;
lazy_static! {
static ref BUF: [String; 16] = [
String::with_capacity(1024), String::with_capacity(1024), String::with_capacity(1024), String::with_capacity(1024),
String::with_capacity(1024), String::with_capacity(1024), String::with_capacity(1024), String::with_capacity(1024),
String::with_capacity(1024), String::with_capacity(1024), String::with_capacity(1024), String::with_capacity(1024),
String::with_capacity(1024), String::with_capacity(1024), String::with_capacity(1024), String::with_capacity(1024)
];
static ref BUF_INDEX: usize = 0;
}
fn tmpstr() -> &'static mut String {
let index_ptr: * const usize = &*BUF_INDEX;
let index: &'static mut usize = unsafe { mem::transmute(index_ptr) };
let buf_ptr: * const String = &BUF[*index];
let ret: &'static mut String = unsafe { mem::transmute(buf_ptr) };
ret.truncate(0);
*index = (*index + 1usize) % BUF.len();
return ret;
}
fn main(){
let s1 = tmpstr();
s1.push_str("Hello, world!");
let s2 = tmpstr();
s2.push_str("And hello world again!");
dbg!(s1, s2);
}
BTW: It's very good idea for embedded systems.
- moonchild 5y agoYes, of course you can express this in rust. The topic at hand is whether it can be expressed in terms of rust's ownership policies. Your example shows that it cannot; it returns an object of static lifetime, avoiding the issue completely.
- littlestymaar 5y agoThe topic at hand was about the comparison between C and Rust in terms of memory model. Ownership policies are one restriction safe Rust uses to ensure that the user is adhering to its memory model, but Rust is not limited to safe Rust and you can op-out ownership policies if you use raw pointers. The difference between Rust and C in terms of memory model isn't ownership, it's “mutable xor shared”.
- drran 5y agoI cannot understand your question about "ownership policies". Rust have only one ownership policy: one owner per object. It's possible to use pointers to circumvent the restriction and then control when object is destructed using ManuallyDrop[0], so burden of memory bookkeeping will be shifted from Rust compiler to the programmer. [0]: https://doc.rust-lang.org/core/mem/struct.ManuallyDrop.html https://doc.rust-lang.org/core/mem/struct.ManuallyDrop.html
- scoutt 5y agoBut String is heap allocated, right? Can you just declare a static array and return a pointer pointing to any part of it? Like in the C example? BUF is also visible to other parts of the program, correct? If so, it's not quite similar to the C example.
- littlestymaar 5y ago> Can you just declare a static array and return a pointer pointing to any part of it? Like in the C example? Indeed: lazy_static! { static ref BUF: [[u8;1024]; 16] = [ [0;1024], [0;1024], [0;1024], [0;1024], [0;1024], [0;1024], [0;1024], [0;1024], [0;1024], [0;1024], [0;1024], [0;1024], [0;1024], [0;1024], [0;1024], [0;1024]]; static ref BUF_INDEX: usize = 0; } (You'll need to re-implement a `push_str` method on arrays yourself though) > BUF is also visible to other parts of the program, correct? If so, it's not quite similar to the C example. No, because it's not marked as `pub`, nobody outside the current module can access it.
- drran 5y agoString is heap allocated by default, but String can be made from raw pointer to buffer and buffer length: https://doc.rust-lang.org/std/string/struct.String.html#method.from_raw_parts https://doc.rust-lang.org/std/string/struct.String.html#meth... . Yes, of course. BTW: You can use a c2rust converter to convert a C code to it exact equivalent in Rust. No, buf is not exported, so it's "static" in C terminology.
- scoutt 5y ago> No, buf is not exported, so it's "static" in C terminology. Yes, I know that is not exported. What I wanted to say is that in the C example, no one outside tmpstr(void) can access static char buf[16][1024]. In the Rust example I can access static ref BUF from fn main() function, for example.
- littlestymaar 5y ago> In the Rust example I can access static ref BUF from fn main() function, for example. Only because in that simple example, BUF was defined directly in the main module. In a more realistic exemple, BUF and tmpstr would belong to their own module, with only tmpstr being exported (and then accessible). See: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5ab2b41b09a19806de5fdb0922a279ca https://play.rust-lang.org/?version=stable&mode=debug&editio...