Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upRFC: Add #[repr(align = "N")] #1358
Conversation
alexcrichton
added
the
T-lang
label
Nov 9, 2015
alexcrichton
self-assigned this
Nov 9, 2015
This comment has been minimized.
This comment has been minimized.
|
cc #325, an RFC issue also about this. |
This comment has been minimized.
This comment has been minimized.
|
I wish we had arbitrary tokens in attributes, to make this nicer. #[repr(align("32"))] #[repr(align("16"))]
struct Foo(u8);#[repr(align("16"), align("32"))]
struct Foo(u8);#[repr(align("32"))]
struct Foo(u8); |
This comment has been minimized.
This comment has been minimized.
comex
commented
Nov 10, 2015
|
Why the quotes? It would be certainly be nicer to be able to specify any constant expression. |
This comment has been minimized.
This comment has been minimized.
|
Yeah unfortunately the syntax for attributes doesn't allow Currently |
This comment has been minimized.
This comment has been minimized.
erickt
commented
Nov 10, 2015
|
It's probably best for this to be another rfc, but I think we should consider allowing the |
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton Ah, right, if we need token trees in that case, too, I'd take |
This comment has been minimized.
This comment has been minimized.
briansmith
commented
Nov 16, 2015
|
I don't think it makes sense to use RE: "Working with a raw integer, however, should provide the building block for building up other abstractions and should be maximally flexible," what are those "other abstractions"? |
This comment has been minimized.
This comment has been minimized.
Ah in rust-lang/rust#17537 a suggestion was made to have symbolic alignment (e.g. "aligned as much as this other type"). For example the compiler could possibly accept something like |
This comment has been minimized.
This comment has been minimized.
briansmith
commented
Nov 16, 2015
I'm having a hard time understanding this.
In particular, it seems bad to put identifiers and integers in quotes for no reason. Quotes should be reserved for strings. More generally, less noise is better, and the quotes are noise, as is the use of "=" and the use of "repr". |
This comment has been minimized.
This comment has been minimized.
|
What I want specifically is the equivalent of
https://msdn.microsoft.com/en-us/library/xh3e3fd0.aspx This RFC does not look like it does that. |
This comment has been minimized.
This comment has been minimized.
|
@briansmith currently there's a difference between "this parses" and "the compiler rejects this". The syntax for attributes simply does not allow integers or values of the form @retep998 sure, this may not exhaustively cover all possibilities of alignment right out the gate, but the idea is to hit as many as possible and to enable other possibilities in perhaps less ergonomic ways immediately while leaving the door open for future improvements. |
This comment has been minimized.
This comment has been minimized.
ruuda
commented
Nov 16, 2015
|
How does this interact with heap allocating? The documentation for
However, the page size can differ across systems. Should there be an upper bound on the alignment? |
This comment has been minimized.
This comment has been minimized.
|
Seems like a good starting point to me. It does seem like we want to have some sort of limit regarding page-size, but I guess that's mostly a technicality in practice. @alexcrichton do you in fact intend to allow multiple |
This comment has been minimized.
This comment has been minimized.
|
(Incidentally, I agree we should extend attribute syntax to include token trees in some form, but as a separate RFC. After that we could deprecate the use of a string constant here (or just accept both.)) |
huonw
reviewed
Nov 17, 2015
| * Alignment values must be a power of two. | ||
|
|
||
| A custom alignment cannot *decrease* the alignment of a structure unless it is | ||
| also declared with `#[repr(packed)]` (to mirror what C does in this regard), but |
This comment has been minimized.
This comment has been minimized.
huonw
Nov 17, 2015
Member
What's the behaviour of something like:
#[repr(packed, align = "2")]
struct Foo {
x: u8,
y: u16
}I assume it has size 4, but there's no padding between the u8 and u16 (i.e. despite the fact that u16 has alignment 2)?
This comment has been minimized.
This comment has been minimized.
eddyb
Nov 17, 2015
Member
Only if you include trailing padding (which we should do something about, at some point).
This comment has been minimized.
This comment has been minimized.
alexcrichton
Nov 17, 2015
Author
Member
The behavior will likely just mirror what C does for now, e.g.:
#include <stddef.h>
#include <stdalign.h>
#include <stdio.h>
struct foo {
char a;
short b;
} __attribute__((packed, aligned(2)));
int main() {
printf("size: %d\n", (int) sizeof(struct foo));
printf("align: %d\n", (int) alignof(struct foo));
printf("a: %d\n", (int) offsetof(struct foo, a));
printf("b: %d\n", (int) offsetof(struct foo, b));
} $ gcc foo.c && ./a.out
size: 4
align: 2
a: 0
b: 1
This comment has been minimized.
This comment has been minimized.
|
Since this only increases the alignment, I'd prefer if it wasn't named |
This comment has been minimized.
This comment has been minimized.
|
@retep998 This is why I prefer |
This comment has been minimized.
This comment has been minimized.
|
Yeah I'd intend to accept multiple alignment attributes here and the compiler would basically just take the max (e.g. it's correct that the alignment specified would be the minimum-ish). |
This comment has been minimized.
This comment has been minimized.
eternaleye
commented
Nov 17, 2015
|
@alexcrichton: Is it, though? If I have some type that I need to interoperate with a coal-burning PCI card imported from Outer Elbonia with |
This comment has been minimized.
This comment has been minimized.
|
I'm curious as to why multiple alignment attributes would be a useful feature. Can someone please give an example of why someone would do this? |
This comment has been minimized.
This comment has been minimized.
|
@eternaleye ah yeah I guess it is, I vaguely remember coming across something where the alignment ended up being less but thinking again I don't think that's the case. Note that factorization and such don't matter as alignment is always a power of two (e.g. custom alignment has this requirement as well). @mark-i-m In terms of composability it's often nice to just add extra restrictions later on without explicitly going back and removing the prior ones. For example if a macro generated something with |
This comment has been minimized.
This comment has been minimized.
|
+1
|
This comment has been minimized.
This comment has been minimized.
|
This RFC should correlate to the behavior of I started an RFC for the |
This comment has been minimized.
This comment has been minimized.
|
Could we have a too-small align be a warning, rather than an error? The RFC doesn't state it explicitly, but it's implied to be an error. Macros and generic code could legitimately end up with this case (if you need at least N alignment, but higher alignment is fine). If I'm wrong about what the RFC means, I would like it to be clarified. Also, how about extending this to be applicable to individual fields? A |
This comment has been minimized.
This comment has been minimized.
|
Note that when combined with my pack RFC, this results in a very interesting edge case. Specifically the required alignment of any type is 1, unless the alignment is manually specified with So basically we need to decide whether we want the interaction semantics between |
This comment has been minimized.
This comment has been minimized.
|
That's a false choice, I think. It really needs to be either, depending on the ABI in use. |
This comment has been minimized.
This comment has been minimized.
|
I've pushed a commit which indicates that |
This comment has been minimized.
This comment has been minimized.
|
So you're going the gcc route, where alignment attributes on a struct raise the overall alignment of the struct but it still behaves the same as a naturally aligned struct. A struct whose alignment was raised by |
This comment has been minimized.
This comment has been minimized.
matthieu-m
commented
Apr 29, 2016
•
|
Would this RFC allow something akin to C++11:
to get memory storage suitably sized and aligned to store a I've come across the usecase while trying to build a Note that if this RFC is not suitable for this, this is not an issue, an intrinsic or built-in could always be created for it. |
This comment has been minimized.
This comment has been minimized.
|
@matthieu-m If I'm understanding correctly, you want to use |
This comment has been minimized.
This comment has been minimized.
TrianglesPCT
commented
May 1, 2016
|
Can you use this on individual instances, or only on type declarations? Like in C++: // every object of type sse_t will be aligned to 16-byte boundary // the array "cacheline" will be aligned to 128-byte boundary Same keyword works in both cases |
This comment has been minimized.
This comment has been minimized.
|
@TrianglesPCT I might be wrong, but I'm not aware that attributes can be used on individual instances. |
This comment has been minimized.
This comment has been minimized.
|
At the @rust-lang/lang meeting, we decided not to decide on this just yet, because we were all a little confused by the back-and-forth on alignment. =) The text that @alexcrichton added to the RFC says that
But, given that the
this sentence seems somewhat incorrect. Reading this comment from @alexcrichton somewhat clarified the intention: I believe the idea is that the
Here, the natural alignment of the struct refers (presumably) to the maximum alignment of any individual field. (I don't believe that is clearly defined in the RFC itself, though I may be missing something.) So, first, @alexcrichton, do you agree with this summary? Anyway, re-reading the other comments more carefully now, I see that @retep998 has indeed highlighted the key difference here (emphasis mine):
I am not convinced that there is a "right choice" in this situation. The interaction with ABI compatibility, in particular, seems concerning. I can certainly imagine wanting the ability to "match" the behavior of the target C ABI, and yet I am not crazy about having Rust's layout be so tied to what the local C compiler does. But whether we pick "GNU" or "MSVC" style, we will be out of sync with the C conventions on some platform. This seems like a place where (As an aside, clearly we must work out the interaction of align and custom packed values, since we adopted the packed RFC, but I also agree with @retep998 that this was an issue before.) |
This comment has been minimized.
This comment has been minimized.
Indeed! Apologies if the RFC is a bit confusing, I seem to have a tendency to do that lately... But yes my assumption was that
Yes, I'm personally a fan of having understandable Rust semantics and then we can have shims to have compatibility with C as necessary. |
This comment has been minimized.
This comment has been minimized.
|
Discussed again in the @rust-lang/lang meeting. We feel like there is no clear right answer here, as I summarized before. Given the lack of feedback and experience, we wanted to propose a compromise: just disallow a struct with an explicit alignment attribute from being used inside of a packed struct, this sidestepping the distinction. We can then revisit the interaction between the two in a specific RFC when we have more experience or specific use cases in mind. Thoughts? |
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis that sounds reasonable to me, and to clarify, the rule would look like this, right?
|
This comment has been minimized.
This comment has been minimized.
|
Yes.
|
This comment has been minimized.
This comment has been minimized.
|
Ok, I've pushed an update indicating that it is illegal to mix the two attributes |
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton I'm fine with the edit your posted, but it may be stronger than necessary. That is, I don't think there is a problem with having an "aligned" struct containing a "packed" struct: #[repr(align=16)]
struct Foo {
b: Bar
}
#[repr(packed)]
struct Bar {
x: u8,
y: u16
}Unless I'm missing something? |
This comment has been minimized.
This comment has been minimized.
|
The only issue is when a struct that has |
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis yeah that was intentional, but I've pushed an update now to allow it. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Huzzah! The @rust-lang/lang team has decided to accept this RFC. |
nikomatsakis
referenced this pull request
May 13, 2016
Closed
implement `#[repr(align)]` (tracking issue for RFC 1358) #33626
This comment has been minimized.
This comment has been minimized.
|
Tracking issue: rust-lang/rust#33626 If you'd like to keep following the development of this feature, please subscribe to that issue, thanks! :) |
alexcrichton commentedNov 9, 2015
•
edited by mbrubeck
Extend the existing
#[repr]attribute on structs with analign = "N"optionto specify a custom alignment for
structtypes.Rendered