Search code examples
rustffi

Pass mutable pointer to function without initializing it first


use std::ptr::{addr_of_mut, null_mut};

use libc::{CLOCK_MONOTONIC, timer_create, timer_delete, timer_t};

fn main() {
    let mut timer1: timer_t = null_mut();

    unsafe {
        let r = timer_create(CLOCK_MONOTONIC, null_mut(), addr_of_mut!(timer1));
        if r == 0 {
            timer_delete(timer1);
        }
    }
}

When calling timer_create(), the resulting timer ID is stored at variable timer1. I pass it as a mutable pointer, so that's the output variable.

How can I avoid initializing timer1 to null_mut() as in the code above knowing that it's guaranteed by the API to be safe ?


Solution

  • You can use MaybeUninit:

    use std::mem::MaybeUninit;
    use std::ptr::null_mut;
    
    use libc::{CLOCK_MONOTONIC, timer_create, timer_delete, timer_t};
    
    fn main() {
        let mut timer1 = MaybeUninit::<timer_t>::uninit();
        let timer1 = unsafe {
            let r = timer_create(CLOCK_MONOTONIC, null_mut(), timer1.as_mut_ptr());
            if r != 0 {
                panic!("…");
            }
            timer1.assume_init()
        };
        unsafe {
            timer_delete(timer1);
        }
    }