-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
What it does
Unions in rust have unspecified layout by default, despite many people thinking that they lay out each type at the start of the union (like C does)
Lint Name
unspecified_layout_union
Category
pedantic
Advantage
If the user intended the union to be #[repr(C)] because they are using it to read fields other than the most recently written one, the code becomes defined behaviour.
If the user did not intend any specific representation because they are using it in an externally tagged way, the #[allow(unspecified_layout_union)] calls this out specifically.
Drawbacks
Some unions don't rely on the representation being C-like, and this may be the majority of the unions that have no explicit representation.
This lint, once added, would fire on all of these unions, as it's currently impossible to specify the rust repr explicitly. This might be a source of noise. I originally thought about suspicious as a category for this lint, but downgraded it to pedantic because of that.
Example
union Foo {
a: i32,
b: u32,
}
fn main() {
let _x: u32 = unsafe {
Foo { a: 0_i32 }.b // UB, `b` is allowed to be padding
};
}Could be written as:
#[repr(C)]
union Foo {
a: i32,
b: u32,
}
fn main() {
let _x: u32 = unsafe {
Foo { a: 0_i32 }.b // Now defined behaviour, this is just an i32 -> u32 transmute.
};
}