Is there way to get raw pointer to field without dereferencing struct

I am specifically ask about new &raw const/&raw mut syntax.

I know that I can just use addr_of in std::ptr - Rust macro.

E.g. if I have struct

struct S {
  a: u32,
  b: u32,
}

how I express core::ptr::addr_of!((*s).a) using new syntax?

&raw is just a better syntax for addr_of! β€” it doesn't change what you can do with it.

addr_of!(expr) is equivalent to &raw const expr. The macro is soft-deprecated; use &raw const instead.

β€” addr_of in std::ptr - Rust

If you need to dereference you must have some sort of pointer to the struct, not just the struct. What type of pointer is it? For what purpose are you concerned about the dereference?

I was just confused why &raw const (*p).field requires unsafe.

It’s not &raw but *p that is relevant here. A dereference of a raw pointer is unsafe, and must be so even in this case because if the pointer was invalid, it could produce an out-of-bounds pointer. The addr_of! documentation (which can be understood as describing &raw too, until &raw gets proper documentation of its own) mentions this:

This means that addr_of!((*ptr).field) still requires the projection to field to be in-bounds, using the same rules as offset.

struct S {
  a: u32,
  b: u32,
}
fn main() {
    let s = S { a: 1, b: 2 };
    let sp = &raw const s;
    let ap = std::ptr::addr_of!((*sp).a);
    let bp = &raw const (*sp).b;
}
error[E0133]: dereference of raw pointer is unsafe and requires unsafe block
 --> src/main.rs:8:33
  |
8 |     let ap = std::ptr::addr_of!((*sp).a);
  |                                 ^^^^^ dereference of raw pointer

error[E0133]: dereference of raw pointer is unsafe and requires unsafe block
 --> src/main.rs:9:25
  |
9 |     let bp = &raw const (*sp).b;
  |                         ^^^^^ dereference of raw pointer

But dereferencing a reference (or Box, etc.) is safe, so you can use &raw in safe code; this compiles:

struct S {
  a: u32,
  b: u32,
}
fn main() {
    let s = S { a: 1, b: 2 };
    let sp = &s;
    let ap = std::ptr::addr_of!((*sp).a);
    let bp = &raw const (*sp).b;
}

And you can omit the explicit dereference operator too:

    let ap = std::ptr::addr_of!(sp.a);
    let bp = &raw const sp.b;
2 Likes