If you want different behavior at compile time versus run time, just use different functions.
I want to provide a consistent interface to my user, that is a concern.
I'm wondering if there's a misunderstanding of Rust const
here, as I don't see why the constness of the parameters matters in the example.
To my understanding, const value/expression can be evaluated during compile-time, and based on this we can take optimization during compiling other than runtime.
Take the example below:
const START: usize = 8;
const LEN: usize = 16;
fn set_bit(arr: &mut [u8], start: usize, len: usize) {
if start % 8 == 0 && len % 8 == 0 {
let s = start / 8;
let e = s + (len / 8);
arr[s..e].fill(1);
return
}
if len > 8 {
let start = ((start + 8) / 8) as usize * 8;
let len = (len / 8) as usize * 8;
set_bit(arr, start, len);
}
if start % 8 != 0 {
let first_byte_mask = !(0 as u8) << (start % 8);
arr[start / 8] = first_byte_mask;
}
let end = start + len;
if end % 8 != 0 {
let last_byte_mask = !(0 as u8) >> (8 - (end % 8));
arr[(start + len) / 8] = last_byte_mask;
}
}
fn main() {
let mut arr = [0 as u8; 16];
dbg!(START);
set_bit(&mut arr, START, LEN);
dbg!(arr);
let start = 55;
let len = 10;
set_bit(&mut arr, start, len);
dbg!(arr);
}
When set_bit(&mut arr, START, LEN);
is invoked, the compiler exactly knows the start position and length, and can directly inline this function by a simple memset(arr + START, 0xFF, LEN)
function.
And the the second call to set_bit(&mut arr, start, len);
, the compiler doesn't know the start and len at compile time, and can do a function call as normal.
So, after this optimisation. The main()
function will be something like this:
fn main() {
let mut arr = [0 as u8; 16];
dbg!(START);
memset(arr + START, 0xff, LEN);
dbg!(arr);
let start = 55;
let len = 10;
set_bit(&mut arr, start, len);
dbg!(arr);
}
Additionally, libc::memset
is both unsafe
and not const
(i.e. your example can't work in a const
context).
I use memset()
function here for conception proven. What I mean here is that the compiler can simply expand this code snippet to a rep stosb
in assembly instead of complex instructions.