user7494493
user7494493

Reputation:

How to pass uninitialized variable address in Unsafe Rust

Following code throws an error

borrow of possibly-uninitialized variable: ires

pub fn new(t: QueryType) -> QueryObject
{
    unsafe {
        let mut ires: u32;
        gl::GenQueries(1, &mut ires as *mut u32);
        
        let res = QueryObject {
            index: ires,
            qtype: t as u32,
            status: QueryStatus::Inactive as u32,
        };

        return res;
    }
}

How should I pass the variable address without initializing variable ires

Upvotes: 3

Views: 1174

Answers (2)

Gymore
Gymore

Reputation: 605

You can use MaybeUninit to tell the compiler the bit pattern of a value may not be a valid bit pattern.

let ires = std::mem::MaybeUninit::uninit();
gl::GenQueries(1, ires.as_mut_ptr());
let ires = unsafe { ires.assume_init() };

By using assume_init, you're telling the compiler that you've checked that ires is a valid initialized value. If you didn't, undefined behavior can occur. In this case, if you're sure 100% that gl::GenQueries will not try to read this value, giving it uninitialized memory should be fine. I say "should" because it is still a debate whether uninitialized integers are valid integers.

Be really careful with uninitialized memory. If you want to play with it, I suggest you to check out this blog post.

Upvotes: 2

vallentin
vallentin

Reputation: 26245

Ideally, it's because Rust can't guarantee that gl::GenQueries() doesn't attempt to read from ires before it is initialized. Therefore you must always initialize before you attempt to borrow.

To resolve the issue, you just have to initialize it with 0. You can also simplify &mut ires as *mut u32 to just &mut ires.

let mut ires: u32 = 0;
gl::GenQueries(1, &mut ires);

Even if you were able to bypass "borrow of possibly-uninitialized variable". Then you would subsequently just receive "use of possibly-uninitialized variable". As there's no guarantees that gl::GenQueries() initialized ires.

The cost of initializing a u32 is negligible. However, if you insist then check out MaybeUninit.

Upvotes: 1

Related Questions