Skip to content
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(4))] struct has 8 byte alignment #48159

Open
gnzlbg opened this issue Feb 12, 2018 · 11 comments
Open

#[repr(align(4))] struct has 8 byte alignment #48159

gnzlbg opened this issue Feb 12, 2018 · 11 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-feature-request Category: A feature request, i.e: not implemented / a PR. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@gnzlbg
Copy link
Contributor

gnzlbg commented Feb 12, 2018

See it live:

#![allow(non_camel_case_types)]
pub enum c_void {}

type uintptr_t = usize;
type int16_t = u16;
type uint16_t = int16_t;
type uint32_t = u32;
type intptr_t = uintptr_t;

#[repr(C)]
#[repr(align(4))]
pub struct kevent {
    pub ident: uintptr_t,
    pub filter: int16_t,
    pub flags: uint16_t,
    pub fflags: uint32_t,
    pub data: intptr_t,
    pub udata: *mut c_void,
}

fn main() {
    assert_eq!(::std::mem::align_of::<kevent>(), 4); // ERROR: 8 != 4
}

No warning, no error, nu nothing.

This is rust-lang/libc#914

@kennytm
Copy link
Member

kennytm commented Feb 12, 2018

cc #33626

If we follow the text of the original RFC 1358, this is intended:

// Lowering has no effect
#[repr(align = "1")]
struct Align1(i32);

so the problem is missing diagnostic. Not sure if portability lint is needed due to the pointer-sized things.

@kennytm kennytm added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. A-diagnostics Area: Messages for errors, warnings, and lints C-feature-request Category: A feature request, i.e: not implemented / a PR. and removed C-bug Category: This is a bug. labels Feb 12, 2018
@gnzlbg
Copy link
Contributor Author

gnzlbg commented Feb 12, 2018

Might be that what we need here is just repr(packed): #33158

@retep998
Copy link
Member

It would be nice to have a lint to warn you you when #[repr(align(N))] has no effect due to the struct's natural alignment already being that high.

@parched
Copy link
Contributor

parched commented Feb 14, 2018

How would that lint work portably? What say you wanted 8 byte alignment on all targets with

#[repr(align = "8")]
struct Align8(usize);

the lint would fire on 64-bit targets.

@retep998
Copy link
Member

In that case you can just #[allow(whatever_the_lint_name_is_idk)]

@hanna-kruppe
Copy link
Contributor

Or use #[cfg_attr(not(target_pointer_width="8"), repr(align(8)))]

@Boscop
Copy link

Boscop commented Jun 13, 2020

Btw, why doesn't #[repr(align(16))] work on struct members?
It's inconvenient to have to wrap a member in another type just to specify the alignment.

@retep998
Copy link
Member

Probably because you can't do that in C. At least for __declspec(align) it cannot be applied to individual fields.

@Boscop
Copy link

Boscop commented Jun 13, 2020

@retep998 Just because it's not possible in C doesn't mean it can't be possible in LLVM / Rust. Even if it's only possible on a struct, rustc could auto-generate a wrapper struct for the codegen and auto-wrap the member in it, if it has that attribute.

@retep998
Copy link
Member

@Boscop I'm not saying we shouldn't have that feature, I'm just explaining why we don't have that yet. Feel free to open an issue or PR about that extension of #[repr(align)]. This issue isn't really the place for it.

@comex
Copy link
Contributor

comex commented Jul 13, 2020

Prior art: In C++, an alignas specifier lower than the natural alignment is a hard error. (Reference: this page; search for "ill-formed".)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-feature-request Category: A feature request, i.e: not implemented / a PR. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants