Gilnaa / memoffset

offsetof for Rust
MIT License
224 stars 29 forks source link

is offset_of! meaningful if a struct does not have repr(C)? #59

Closed godmar closed 2 years ago

godmar commented 3 years ago

[This is perhaps more of a documentation request - it's information I might have expected to find in the README]

I understand that Rust generally does not make any guarantees regarding the layout of structs. The book states:

Type layout can be changed with each compilation. Instead of trying to document exactly what is done, we only document what is guaranteed today.

If you apply offset_of! to a struct with the default representation, do you get garbage, or do you get whatever the offset is under the current compiler and current compilation pass?

Gilnaa commented 3 years ago

The latter. You get a correct and valid offset, but you cannot rely on it to stay the same between compilations.

RalfJung commented 3 years ago

Note that the offset might be different even for different instances of the same generic type, e.g. if you get the offset for Foo<i32> that says nothing about the offset for Foo<u32>.

RalfJung commented 3 years ago

So, I think the recommendation is to not try and play offset games with repr(Rust) types, at least until there is more solid documentation about this at https://github.com/rust-lang/unsafe-code-guidelines/.

Gilnaa commented 3 years ago

It's probably rarely used, if at all, but it dawned on me that using span_of! with a repr(Rust) between 2 fields, may return an unexpected descending range if rustc reorders the fields.

Unlike offset_of!, this macro doesn't make much sense at all with repr(Rust). I guess it should at least be documented, but if unused, span_of!(Foo, a..b) should be removed.

I'll go over dependents to see if someone might have used it.

Gilnaa commented 2 years ago

Writing a follow-up to the previous reply in a timely manner. Ran a GitHub search on span_of!. Among a surprising amount of copies of this library vendored into other repositories (I'd say around about 95% of the results), I've found the following.

Some examples of span_of! of being used:

Usage in testing code:


Similar implementation in different crates: https://github.com/CasualX/dataview/blob/17dd899e57189afe494de9fdf23f294c4fc435c4/src/offset_of.rs#L86


Out of all of these, only one used the inter-field span_of! variant (with repr(C), so, correctly)