Reputation:
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
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
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