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

allow align(0) on struct fields #3802

Closed
andrewrk opened this issue Nov 29, 2019 · 4 comments
Closed

allow align(0) on struct fields #3802

andrewrk opened this issue Nov 29, 2019 · 4 comments
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@andrewrk
Copy link
Member

This is a sister issue to #3133. Packed structs offer a way to explicitly provide the layout of a struct in memory. But non-packed structs also can offer something powerful: the ability to say that you do not need a field to be aligned to a byte boundary.

const S = struct {
    a: bool align(0),
    b: u8,
    c: bool align(0),
    d: bool align(0),
    e: bool align(0),
};

Because structs do not guarantee field order, Zig is allowed to put a, c, d, and e fields into 1 byte, making the entire struct only 2 bytes, rather than 5.

The compromise here is that pointers to align(0) fields have pointer metadata in the type that prevents it from being coerced to a "normal" pointer for that type. This the same thing as taking a pointer of a non-byte-aligned packed struct field.

However this would be quite useful for flags, where one typically does not need a pointer to an individual flag. Rather, one typically accesses flags from a base pointer, which would work just fine with align(0) flag fields.

@andrewrk andrewrk added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Nov 29, 2019
@andrewrk andrewrk added this to the 0.7.0 milestone Nov 29, 2019
@JesseRMeyer
Copy link

Is there a reason why someone wouldn't first reach for embedding a packed struct inside a normal struct for bitflags before trying this? I do see the general appeal of making align(0) well defined, an in the manner you've described, but specifically for flags, there are already, seemingly simpler, more controlled ways of accomplishing the task. Overall, I think that when operating at the bit level, one's mind is probably wanting data laid out carefully rather than letting the compiler take the wheel.

@andrewrk
Copy link
Member Author

A packed struct has a well-defined in-memory layout. If you do not need this, then it is better to avoid it, for plenty of reasons:

  • Zig is allowed to re-order fields for performance (e.g. profile-guided optimization), better memory usage, or safety reasons
  • Zig is allowed to insert an additional field for safety purposes, or padding for hot code swapping (hot code swapping #68) or incremental compilation
  • Type safety for @ptrCast and other related functions is possible (not implemented yet) when the type has no well-defined in-memory layout
  • Detection of undefined values is possible (not implemented yet) when the type has no well-defined in-memory layout

However if you need well-defined in-memory layout, that's fine, that's what packed structs are for.

@andrewrk andrewrk added the accepted This proposal is planned. label Dec 16, 2019
@daurnimator
Copy link
Contributor

Shouldn't align(0) work on types in the general case? e.g. [1024] align(0) bool for a packed array of booleans

@andrewrk
Copy link
Member Author

Rejected in favor of #5049 and #10113.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

3 participants