Skip to content

Can I create and use a *mut to an uninitialized local? #90718

Open
@ecstatic-morse

Description

@ecstatic-morse

The following code does not compile on current nightly or stable (1.56.1).

fn main() {
    let mut x: i32;
    println!("{:p}", std::ptr::addr_of_mut!(x));
}
error[E0381]: borrow of possibly-uninitialized variable: `x`
 --> src/main.rs:3:22
  |
3 |     println!("{:p}", std::ptr::addr_of_mut!(x));
  |                      ^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `x`
  |
  = note: this error originates in the macro `std::ptr::addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info)

I would expect this to work, since part of the rationale for the addr_of macro and raw reference operator (#64490) was to allow creation of pointers to uninitialized memory. On the other hand, I don't think the behavior of locals that are only assigned/accessed indirectly is fully specified (though I don't think my example is UB). Such locals will never be dropped, which might be surprising, and they cannot be used directly, even after being written via the pointer, without encountering the same error.

MaybeUninit is basically always a better choice for these kinds of things, so it shouldn't be of much importance to users. However, we should avoid depending on the illegality of such code inside the compiler–a more complex example arose while discussing region inference–unless we have made a conscious decision to forbid it. Alternatively, if interacting with uninitialized locals is well-defined, we should probably make addr_of work on them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-raw-pointersArea: raw pointers, MaybeUninit, NonNull

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions