Skip to content

Replace __align fields with #[repr(align(x))] #1042

Closed
@faern

Description

@faern

This has been briefly touched in #963 and #58 but this issue intend to discuss it from a different angle.

When I grep in the libc repository I find 123 instances of __align:. The main problem is that instantiating a struct that uses this way to achieve alignment requires:

let mut foo: libc::some_struct = unsafe { mem::uninitialized() };
foo.field = my_value;

Which has many downsides, mainly

  • needing unsafe
  • has to be assigned to a mutable variable
  • and can't be done in a constant expression.

#repr(align(x))] was introduced in Rust 1.25, which at the time of writing this is only two releases behind current stable. Thus I understand we probably can't bump the required rustc version for libc that high yet. But I could not find any information about how backwards compatible libc intends to be, going forward. Since #972 bumped the required rustc version from 1.0 to 1.13 without much fanfare or breaking version bumping etc I guess there is some unofficial point where even libc don't care about your old compiler anymore.

Switching to #repr(align(x))] would, among removing the need for a lot of unsafe, help in making more things constant expressions. For example this issue where we need to create an in6_addr in an associated constant: rust-lang/rust#44582

Would it count as a breaking change to remove the __align fields? It would change the struct, but not the public part of it, so I guess not. Any code using the mem::uninitialized() dance should still work exactly the same I think.

I'm playing with the thought to somehow make this work in Edition 2018. But I guess compiling a crate with edition = "2018" that has edition 2015 dependencies only compiles libc once, even if crates from both editions depend on it? If it is compiled separately for each edition then something like the following could work (given that there will be such a cfg value to conditionally compile on to begin with):

#[cfg_attr(not(edition = "2015"), repr(align(4)))]
pub struct in6_addr {
    pub s6_addr: [u8; 16],
    #[cfg(edition = "2015")]
    __align: [u32; 0],
}

Another issue that discusses using newer rustc features in order to improve the libc implementation is #1020. Both implementing that issue and this one would raise the rustc version requirement. Although, the other issue would require rustc 1.19, while this is a lot more extreme as it requires 1.25.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions