-
Notifications
You must be signed in to change notification settings - Fork 62
Description
There are some cases where the layout we generate for repr(C) types does not match the current target's C "default" toolchain. The ones I am aware of are all cases where we allow type declarations that go beyond standard C, and we match the behavior of GCC/clang, but that does not match MSVC:
- repr(C) on MSVC targets does not always match MSVC type layout when ZST are involved rust#81996 (This unfortunately started as a collection of a bunch of separate problems. I moved the enum part into a separate issue, and I think everything else is related to zero-sized types, but I am not sure. Would be great if someone could summarize that part, file it as a new issue, and close the old one.)
- This one is related to "Any two types with size 0 and alignment 1 are ABI-compatible" vs the Windows ABI #552
- #[repr(align(N))] fields not allowed in #[repr(packed(M>=N))] structs rust#100743 (the "not allowed" part can be circumvented, and then layout differs between Rust and MSVC)
- repr(C) on an enum accepts discriminants that do not fit into the default C enum size rust#124403
- ABI mismatch between rustc and clang for passing ZSTs using the win64 ABI. rust#132893 is not about
extern "C"
but aboutextern "win64"
which is apparently expected to always match the MSVC ABI - MSVC on x86-32 Windows fails to align variables to their required alignment rust#112480 could be resolved if we had more freedom with
repr(C)
struct layout (givingu64
/i64
usually an alignment of 4, but making it 8 in structs)
We also have a similar problem on AIX:
- Currently we set
f64
alignment to 8 which is wrong as somef64
struct fields are only 4-aligned, but a value of 4 also isn't right since then some structs would not get enough padding.
In many cases part of the problem is that different toolchains behave differently, so in Rust we have to make the choice between "layout that is portable across many targets" and "layout that matches the current target's C toolchain". However, given that the name of the repr in C
and given the crABI project to define a portable ABI, it seems most reasonable to say that repr(C)
should match whatever C does on the given target. That is also what the lang team decided (but not FCP'd as far as I can see). But of course that would be a breaking change...
These issues have been stuck for a while, and I am not sure what is the best way to make progress. Maybe we should have a post-mono lint saying "hey you defined this repr(C)
type but on the current target that doesn't actually behave the way C does, so behavior is planned change in the future"? (It has to be post-mono in general because with generics, it's often not possible to detect pre-mono whether a type falls into this category or not.)