3 ms·
In general, Rust fields are padded such that they aligned to a multiple of their size. Rustc does not offer guarantees on the ordering of the fields. This holds
by PartiallyTyped 3y ago
In general, Rust fields are padded such that they aligned to a multiple of their size. Rustc does not offer guarantees on the ordering of the fields. This holds for all types, not just 128bit values.
This allows rust programs to actually use less memory than C programs.
- kibwen 3y ago> Rustc does not offer guarantees on the ordering of the fields. It's possible to guarantee the layout of a struct by opting into a specific representation, such as the `repr(C)` shown in the OP.
- PartiallyTyped 3y agoThat's a special case and sits at the boundaries / bridge of languages. > There is no indirection for these types; all data is stored within the struct, as you would expect in C. However with the exception of arrays (which are densely packed and in-order), the layout of data is not specified by default. struct A { a: i32, b: u64, } struct B { a: i32, b: u64, } > Rust does guarantee that two instances of A have their data laid out in exactly the same way. However Rust does not currently guarantee that an instance of A has the same field ordering or padding as an instance of B. https://doc.rust-lang.org/nomicon/repr-rust.html https://doc.rust-lang.org/nomicon/repr-rust.html
- codeflo 3y agoIt’s not the default, but it’s just a language feature. It’s also not just for interfacing with C. For example, you also use repr(C) for pointer tricks even if you never leave Rust. Lots of places in the standard library use it for that reason.
- PartiallyTyped 3y agoI don't understand the reaction. > By default, composite structures have an alignment equal to the maximum of their fields' alignments. Rust will consequently insert padding where necessary to ensure that all fields are properly aligned and that the overall type's size is a multiple of its alignment. [...] > There is no indirection for these types; all data is stored within the struct, as you would expect in C. However with the exception of arrays (which are densely packed and in-order), the layout of data is not specified by default. struct A { a: i32, b: u64, } struct B { a: i32, b: u64, } > Rust does guarantee that two instances of A have their data laid out in exactly the same way. However Rust does not currently guarantee that an instance of A has the same field ordering or padding as an instance of B. Here is my source: https://doc.rust-lang.org/nomicon/repr-rust.html https://doc.rust-lang.org/nomicon/repr-rust.html
- omoikane 3y agoMSVC has `pragma pack` that removes padding to reduce memory usage, but I think it preserves field order: https://learn.microsoft.com/en-us/cpp/preprocessor/pack?view=msvc-170 https://learn.microsoft.com/en-us/cpp/preprocessor/pack?view... GCC and Clang also support this pragma: https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Structure-Layout-Pragmas.html https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Structure-Layo... https://clang.llvm.org/docs/UsersManual.html#microsoft-extensions https://clang.llvm.org/docs/UsersManual.html#microsoft-exten...
- PartiallyTyped 3y agoThat's right, you can pack things with a pragma directive in C and C++ for some compilers. Rust can take it a bit further. In rust, fields must be aligned to a multiple of their size, and structs/tuples must be aligned to a multiple of their largest element. This combination makes it very easy to handle memory offsets, or reusing the same representation in a way that reduces memory usage (these are called niches)[1]. This is why dynamic linking is a bit more complex in rust. Alternatively you can offer a C bridge via `extern "c"`. C will act as a bridge between rust and different languages, and at that stage you need to take care of ordering and padding. [1] https://doc.rust-lang.org/nomicon/repr-rust.html https://doc.rust-lang.org/nomicon/repr-rust.html