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 upThere is no syntax for struct alignment #325
Comments
rust-highfive
referenced this issue
Sep 26, 2014
Closed
There is no syntax for struct alignment #17537
This comment has been minimized.
This comment has been minimized.
edef1c
commented
Sep 26, 2014
|
welp, I can't edit this one. - The only way to hack around this is to build a same-sized type out of SIMD types and transmute it when necessary.
+ The only way to hack around this is to prepend your struct with a zero-length array of a SIMD type. |
This comment has been minimized.
This comment has been minimized.
|
@edef1c I updated it for you. |
This comment has been minimized.
This comment has been minimized.
|
@edef1c it's information added to each load/store/manipulation, it's not an inherent property of the LLVM "type", e.g. struct Foo {
int x;
} __attribute__((__aligned__(1024)));
struct Foo f(struct Foo x) {
struct Foo y;
return x;
}compiles to ( ; ModuleID = 'alignment.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
%struct.Foo = type { i32, [1020 x i8] }
; Function Attrs: nounwind uwtable
define void @f(%struct.Foo* noalias sret %agg.result, %struct.Foo* byval align 1024 %x) #0 {
%y = alloca %struct.Foo, align 1024
%1 = bitcast %struct.Foo* %agg.result to i8*
%2 = bitcast %struct.Foo* %x to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 1024, i32 1024, i1 false)
ret void
}
; Function Attrs: nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) #1
attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind } |
This comment has been minimized.
This comment has been minimized.
|
See also rust-lang/rust#4578 |
This comment has been minimized.
This comment has been minimized.
edef1c
commented
Sep 27, 2014
|
@huonw Yep, I discovered that — though Clang seems to get it horribly wrong for my struct (an array of internal align(64) structs has padding /next/ to it — gcc gets it right though) |
This comment has been minimized.
This comment has been minimized.
thestinger
commented
Sep 27, 2014
|
The information added to the loads / stores / parameters is just an optimization. |
This comment has been minimized.
This comment has been minimized.
|
Idly, it would be convenient for some usecases if the checks done for transmute (statically verifying that its two type parameters have the same alignment and size) would be useful in some cases for custom allocators (both would be independently useful, actually--in the case I'm thinking of I would only care about alignment). Then instead of requiring the allocator to track the different size class / aligment pools at runtime, you could explicitly allocate a pool with the class you needed and safely verify it at compile time. It would also allow transmute to be used on types with type parameters as long as they could be bounded to have the same size and alignment. I guess such a type would require associated constants in order to be representable, though. Right now there's no way to provide an interface like this without requiring the client to use unsafe code to transmute his or her type. Looking up, it seems like this has more to do with the closed issue (rust-lang/rust#4578) than this one. |
This comment has been minimized.
This comment has been minimized.
|
I'd like to mention that in some cases the workaround of using a simd type doesn't work. For example in Windows API where some types will have packing specified to be 2, which is greater than what I'd get with |
briansmith
referenced this issue
Nov 1, 2015
Open
Improve FFI safety w.r.t. alignment and sizing #36
This was referenced Apr 13, 2016
withoutboats
pushed a commit
to withoutboats/rfcs
that referenced
this issue
Jan 15, 2017
This comment has been minimized.
This comment has been minimized.
Rufflewind
commented
Apr 24, 2017
|
It would also be nice to have something similar to C++’s |
This comment has been minimized.
This comment has been minimized.
|
Does #1358 not fulfill the needs of this? Or is there something more (besides that RFC) that needs to be implemented in order to close this issue? |
This comment has been minimized.
This comment has been minimized.
Rufflewind
commented
May 31, 2017
|
@Mark-Simulacrum I don't believe it's possible to write |
This comment has been minimized.
This comment has been minimized.
|
You could always do that with |
This comment has been minimized.
This comment has been minimized.
Rufflewind
commented
May 31, 2017
•
|
@eddyb Had no idea that was possible. Thanks! Edit: Still need a way to declare an array of |
This comment has been minimized.
This comment has been minimized.
|
@Mark-Simulacrum I believe #1358 did solve the issue. Still waiting for the feature to stabilize, but it does at least exist. |
This comment has been minimized.
This comment has been minimized.
|
With #1358 merged, I'm going to close this to reduce issue volume. Comment if you disagree! |
rust-highfive commentedSep 26, 2014
•
edited by eddyb
Thursday Sep 25, 2014 at 18:20 GMT
For earlier discussion, see rust-lang/rust#17537
This issue was labelled with: in the Rust repository
Currently, a C struct definition including an alignment hint (
ALIGN(64)) cannot be translated to Rust.Our inability to translate this makes some C ABIs impossible to adhere to, causing crashes and undefined behaviour.
The only way to hack around this is to prepend your struct with a zero-length array of a SIMD type.
We should have some kind of syntax for this. Perhaps
#[align(64)]?@eddyb proposed
#[repr(align(64))], but I fear that complicates thereprattribute a bit much.