Open jeehoonkang opened 3 years ago
Hm, that is unfortunate. But also I do not think there currently is a way to do offset_of!
in Rust without allocating the relevant memory somewhere (and relying on the optimizer to remove it again). We have to avoid this UB:
Dereferencing (using the
*
operator on) a dangling or unaligned raw pointer.
If you are okay with using nightly Rust, an option might be to run offset_of!
in a const
-- then the stack space is used during CTFE and should not impact runtime code.
Maybe we could create a single MaybeUninit::<[u128;N]>
as a static variable somewhere, with some suitably large 'N', and use it for all offset_of-calculations, regardless of type? The argument is that a *const MaybeUninit::<[u128;128]>
surely can be casted safely to a *const MaybeUninit::<(u32,u32)>
, or whatever type the user tried to get the offset for? This would save stack space, but waste static object space.
Example code (which is accepted by Miri): https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4045ba8325b43f0ffd271f1f3119b13e
Only problem is that it'd be hard to determine how large this buffer needs to be. Might be an insurmountable problem.
offset_of! (and probably the other macros in this crate) consumes too much stack space in dev build, especially when the type is big. It's probably because it's declaring a (uninitialized) variable of the type. It's optimized out in the release build.
It affects my workflow in developing an OS in Rust. Its dev build won't boot because offset_of! of a big struct (2KiB) used up the limited amount of kernel stack (4KiB), incurring stack overflow.