-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#[repr(align(N))] fields not allowed in #[repr(packed(M>=N))] structs #100743
Comments
That entire check is anyway somewhat odd since it is easily circumvented: use std::sync::atomic::AtomicU32;
#[repr(C, packed(4))]
struct FooT<T> {
bar: T,
}
type Foo = FooT<AtomicU32>;
fn main() {
let x: Foo = Foo { bar: AtomicU32::new(0) };
} |
So this affects bcachefs - it's a blocker for using Rust more extensively there. In C, specifying packed and aligned will round up the size of the type to the alignment specified, so without this fixed it means we can't generate types in Rust that match the C types for our on disk data structures. |
That's not universally true, GCC and MSVC have different behavior. See the discussion here. So accepting this code in Rust would be a major interop footgun. |
To make progress on this, we need a concrete proposal for what the exact behavior of align(N) fields in packed structs should be, taking into account this problem and also the fact that some code may already exist on stable that could change behavior if we adjust the layout. The comment here could be a good starting point for a proposed solution -- making the resulting layout depend on the target triple (windows-gnu vs windows-msvc). So, if this is a blocker for someone, I suggest looking into sketching a pre-RFC. :) |
No, making it depend on the target triple would not be a good solution - this is important for on the wire formats, the behavior has to be explicitly controllable. Just make it another #[repr] thing. |
And this does need to be fixed; it's a blocker for C FFI. We've worked around it for now in bindgen for bcachefs, but that was a hack and we've been waiting on compiler guys to fix this properly. |
You cannot have both, use it for C FFI and have it fixed independent of the target triple. That's the entire point. So pick one.
|
And given that the repr is called |
"C FFI" is a wider issue than just communicating with code linked in to the same binary. If an on disk format is defined in C, it's a bug if we cannot specify the correct representation. The existing silent different in behaviour between gcc and Microsoft is a bug, and it's perfectly straightforward to fix it here, but you're insisting that it 'can't be helped'. No, you're the one who's got this wrong. "Match the host" should be one option, but it should be specified, per data type, not silently guessed at. |
What's the basis for that claim? Who's wrong, and where's the bugreport? It's not like C has defined struct layout. "Whatever the major C compiler for that target does" is the definition of correct behavior. windows-gnu and windows-msvc are already different ABIs, you can't just call functions across that boundary anyway. There's no basis for demanding that It's also unclear what you are suggesting. Match GCC or match MSVC? I hope you're going to be there to explain to people how they are wrong when they file bugreports that Rust code struct layout doesn't match what their C compiler does? Your attitude isn't helpful here. |
The whole point of packed and aligned is to be able to precisely specify the layout of a given struct. If we have different inconsistent implementations - do you not see the issue? There's no reason Rust has to continue this brokenness - all you have to do is make it possible to specify, on a per type basis, which behavior to emulate. |
If rust doesn't do the same thing as msvc for -msvc targets and as gcc on -gnu targets Rust is broken and will be considered as such by most users. If you want this behavior to change you should take it up with gcc or msvc (depending on which you consider "correct"). |
I think this is getting off topic. Yes, an |
No, this wouldn't be repurposing repr(C) repr(gcc_c) |
This comment was marked as abuse.
This comment was marked as abuse.
And then Being able to request |
This comment by @CAD97 seems relevant
For this issue in particular, the change to using the MSVC layout on MSVC targets would be almost unobservable, except for code that uses generics to bypass the restriction of However, as also noted in that comment, implementing MSVC semantics would require adding a new notion of alignment -- one that trumps outer |
An RFC has been proposed to lift this limitation: rust-lang/rfcs#3718 |
I tried this code:
I expected that
#[repr(align(4))]
fields, such asAtomicU32
, would be allowed inside a#[repr(packed(4))]
struct, since the minimum alignment is >= the required alignment.However, the compiler complains:
Use case: I have some fixed-layout shared memory structs I need to interact with, which sometimes contain unaligned u64s. I also need to use atomics on other parts of them (hopefully only u32s).
Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: