From f5c2b0b2e25e8738cea05cf2c2768c71fbbfb21c Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 24 Mar 2019 13:18:23 -0700 Subject: [PATCH 1/5] Document repr packed(N). --- src/type-layout.md | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/type-layout.md b/src/type-layout.md index 82ee95e566c28..0b4322265fe93 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -119,7 +119,7 @@ representations can be applied to a single type. The representation of a type can be changed by applying the `repr` attribute to it. The following example shows a struct with a `C` representation. -``` +```rust #[repr(C)] struct ThreeInts { first: i16, @@ -148,7 +148,7 @@ There are no guarantees of data layout made by this representation. The `C` representation is designed for dual purposes. One purpose is for creating types that are interoperable with the C Language. The second purpose is -to create types that you can soundly performing operations that rely on data +to create types that you can soundly perform operations on that rely on data layout such as reinterpreting values as a different type. Because of this dual purpose, it is possible to create types that are not useful @@ -205,7 +205,7 @@ The union will have a size of the maximum size of all of its fields rounded to its alignment, and an alignment of the maximum alignment of all of its fields. These maximums may come from different fields. -``` +```rust #[repr(C)] union Union { f1: u16, @@ -280,19 +280,29 @@ The `align` representation can be used on `struct`s and `union`s to raise the alignment of the type to a given value. Alignment is specified as a parameter in the form of `#[repr(align(x))]`. The -alignment value must be a power of two of type `u32`. The `align` representation -can raise the alignment of a type to be greater than it's primitive alignment, -it cannot lower the alignment of a type. +alignment value must be a power of two up to 229. The `align` +representation can raise the alignment of a type to be greater than it's +primitive alignment, it cannot lower the alignment of a type. The `align` and `packed` representations cannot be applied on the same type and a `packed` type cannot transitively contain another `align`ed type. ### The `packed` Representation -The `packed` representation can only be used on `struct`s and `union`s. +The `packed` representation can be used on `struct`s and `union`s to lower the +alignment and padding of the type. + +The packing value is specified as a parameter in the form of +`#[repr(packed(x))]`. If no value is given, as in `#[repr(packed)]`, then the +packing value is 1. The packing value must be a power of two up to +229. -It modifies the representation (either the default or `C`) by removing any -padding bytes and forcing the alignment of the type to `1`. +The `packed` representation sets the alignment to the smaller of the specified +packing and the current alignment (either default or `C`). The alignments of +each field for the purpose of positioning fields would also be the smaller of +the specified packing and the alignment of the type of that field. If the +specified packing is greater than or equal to the default alignment of the +type, then the alignment and layout is unaffected. The `align` and `packed` representations cannot be applied on the same type and a `packed` type cannot transitively contain another `align`ed type. From 915ef66b1be72e69024efe62b687b876aef87e68 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 25 Mar 2019 10:56:38 -0700 Subject: [PATCH 2/5] Apply suggestions from Centril Co-Authored-By: ehuss --- src/type-layout.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/type-layout.md b/src/type-layout.md index 0b4322265fe93..84672b92527bb 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -297,10 +297,10 @@ The packing value is specified as a parameter in the form of packing value is 1. The packing value must be a power of two up to 229. -The `packed` representation sets the alignment to the smaller of the specified +The `packed` representation sets the type's alignment to the smaller of the specified packing and the current alignment (either default or `C`). The alignments of -each field for the purpose of positioning fields would also be the smaller of -the specified packing and the alignment of the type of that field. If the +each field, for the purpose of positioning fields, is the smaller of +the specified packing and the alignment of the field's type. If the specified packing is greater than or equal to the default alignment of the type, then the alignment and layout is unaffected. From a5852ddd01f9637b35250a129e06a551d30f4dac Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 25 Mar 2019 16:17:03 -0700 Subject: [PATCH 3/5] Try a different way to document align/packed. --- src/type-layout.md | 77 ++++++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/src/type-layout.md b/src/type-layout.md index 84672b92527bb..65190204c0256 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -113,8 +113,7 @@ All user-defined composite types (`struct`s, `enum`s, and `union`s) have a *representation* that specifies what the layout is for the type. The possible representations for a type are the default representation, `C`, -the primitive representations, `packed`, and `transparent`. Multiple -representations can be applied to a single type. +the primitive representations, and `transparent`. The representation of a type can be changed by applying the `repr` attribute to it. The following example shows a struct with a `C` representation. @@ -128,14 +127,36 @@ struct ThreeInts { } ``` +The alignment may be raised or lowered with the `align` and `packed` modifiers +respectively. They alter the representation specified in the attribute: + +```rust +// Default representation, alignment lowered to 2. +#[repr(packed(2))] +struct PackedStruct { + first: i16, + second: i8, + third: i32 +} + +// C representation, alignment raised to 8 +#[repr(C, align(8))] +struct AlignedStruct { + first: i16, + second: i8, + third: i32 +} +``` + > Note: As a consequence of the representation being an attribute on the item, > the representation does not depend on generic parameters. Any two types with > the same name have the same representation. For example, `Foo` and > `Foo` both have the same representation. -The representation of a type does not change the layout of its fields. For -example, a struct with a `C` representation that contains a struct `Inner` with -the default representation will not change the layout of Inner. +The representation of a type can change the padding between fields, but does +not change the layout of the fields themselves. For example, a struct with a +`C` representation that contains a struct `Inner` with the default +representation will not change the layout of Inner. ### The Default Representation @@ -274,38 +295,42 @@ For all other enumerations, the layout is unspecified. Likewise, combining two primitive representations together is unspecified. -### The `align` Representation +### The `align` modifier -The `align` representation can be used on `struct`s and `union`s to raise the +The `align` modifier can be used on `struct`s and `union`s to raise the alignment of the type to a given value. -Alignment is specified as a parameter in the form of `#[repr(align(x))]`. The -alignment value must be a power of two up to 229. The `align` -representation can raise the alignment of a type to be greater than it's -primitive alignment, it cannot lower the alignment of a type. +The alignment is specified as an integer parameter in the form of +`#[repr(align(x))]`. The alignment value must be a power of two from 1 up to +229. + +The `align` modifier raises the type's alignment to the specified alignment. +If the specified alignment is less than the alignment of the type without the +`align` modifier, then the alignment is unaffected. -The `align` and `packed` representations cannot be applied on the same type and -a `packed` type cannot transitively contain another `align`ed type. +The `align` and `packed` modifiers cannot be applied on the same type and a +`packed` type cannot transitively contain another `align`ed type. `align` may +only be applied to the default and `C` representations. -### The `packed` Representation +### The `packed` modifier -The `packed` representation can be used on `struct`s and `union`s to lower the -alignment and padding of the type. +The `packed` modifier can be used on `struct`s and `union`s to lower the +alignment of the type to a given value. -The packing value is specified as a parameter in the form of +The packing value is specified as an integer parameter in the form of `#[repr(packed(x))]`. If no value is given, as in `#[repr(packed)]`, then the -packing value is 1. The packing value must be a power of two up to +packing value is 1. The packing value must be a power of two from 1 up to 229. -The `packed` representation sets the type's alignment to the smaller of the specified -packing and the current alignment (either default or `C`). The alignments of -each field, for the purpose of positioning fields, is the smaller of -the specified packing and the alignment of the field's type. If the -specified packing is greater than or equal to the default alignment of the -type, then the alignment and layout is unaffected. +The `packed` modifier lowers the type's alignment to the specified packing. If +the specified packing is greater to the alignment of the type without the +`packed` modifier, then the alignment and layout is unaffected. The alignments +of each field, for the purpose of positioning fields, is the smaller of the +specified packing and the alignment of the field's type. -The `align` and `packed` representations cannot be applied on the same type and -a `packed` type cannot transitively contain another `align`ed type. +The `align` and `packed` modifiers cannot be applied on the same type and a +`packed` type cannot transitively contain another `align`ed type. `packed` may +only be applied to the default and `C` representations.
From 597d7274079bfb80802efbbf6340b587a1f5d570 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 26 Mar 2019 10:49:32 -0700 Subject: [PATCH 4/5] Apply suggestions from Centril Co-Authored-By: ehuss --- src/type-layout.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/type-layout.md b/src/type-layout.md index 65190204c0256..92e332f96f1f4 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -128,7 +128,8 @@ struct ThreeInts { ``` The alignment may be raised or lowered with the `align` and `packed` modifiers -respectively. They alter the representation specified in the attribute: +respectively. They alter the representation specified in the attribute. +If no representation is specified, the default one is altered. ```rust // Default representation, alignment lowered to 2. @@ -156,7 +157,7 @@ struct AlignedStruct { The representation of a type can change the padding between fields, but does not change the layout of the fields themselves. For example, a struct with a `C` representation that contains a struct `Inner` with the default -representation will not change the layout of Inner. +representation will not change the layout of `Inner`. ### The Default Representation @@ -317,13 +318,13 @@ only be applied to the default and `C` representations. The `packed` modifier can be used on `struct`s and `union`s to lower the alignment of the type to a given value. -The packing value is specified as an integer parameter in the form of +The packing value (hence: "value") is specified as an integer parameter in the form of `#[repr(packed(x))]`. If no value is given, as in `#[repr(packed)]`, then the -packing value is 1. The packing value must be a power of two from 1 up to +value is 1. The value must be a power of two from 1 up to 229. -The `packed` modifier lowers the type's alignment to the specified packing. If -the specified packing is greater to the alignment of the type without the +The `packed` modifier lowers the type's alignment to the specified value. If +the specified value is greater than the type's alignment without the `packed` modifier, then the alignment and layout is unaffected. The alignments of each field, for the purpose of positioning fields, is the smaller of the specified packing and the alignment of the field's type. From 38b408ab6420101cf4ce1b0ba2591c6a57124c29 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 26 Mar 2019 11:29:50 -0700 Subject: [PATCH 5/5] Attempt to remove duplication between `align` and `packed`. --- src/type-layout.md | 57 ++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/src/type-layout.md b/src/type-layout.md index 92e332f96f1f4..84c643f965de5 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -110,10 +110,13 @@ Closures have no layout guarantees. ## Representations All user-defined composite types (`struct`s, `enum`s, and `union`s) have a -*representation* that specifies what the layout is for the type. +*representation* that specifies what the layout is for the type. The possible +representations for a type are: -The possible representations for a type are the default representation, `C`, -the primitive representations, and `transparent`. +- [Default] +- [`C`] +- The [primitive representations] +- [`transparent`] The representation of a type can be changed by applying the `repr` attribute to it. The following example shows a struct with a `C` representation. @@ -296,42 +299,28 @@ For all other enumerations, the layout is unspecified. Likewise, combining two primitive representations together is unspecified. -### The `align` modifier +### The alignment modifiers -The `align` modifier can be used on `struct`s and `union`s to raise the -alignment of the type to a given value. +The `align` and `packed` modifiers can be used to respectively raise or lower +the alignment of `struct`s and `union`s. `packed` may also alter the padding +between fields. The alignment is specified as an integer parameter in the form of -`#[repr(align(x))]`. The alignment value must be a power of two from 1 up to -229. +`#[repr(align(x))]` or `#[repr(packed(x))]`. The alignment value must be a +power of two from 1 up to 229. For `packed`, if no value is given, +as in `#[repr(packed)]`, then the value is 1. -The `align` modifier raises the type's alignment to the specified alignment. -If the specified alignment is less than the alignment of the type without the -`align` modifier, then the alignment is unaffected. +For `align`, if the specified alignment is less than the alignment of the type +without the `align` modifier, then the alignment is unaffected. -The `align` and `packed` modifiers cannot be applied on the same type and a -`packed` type cannot transitively contain another `align`ed type. `align` may -only be applied to the default and `C` representations. - -### The `packed` modifier - -The `packed` modifier can be used on `struct`s and `union`s to lower the -alignment of the type to a given value. - -The packing value (hence: "value") is specified as an integer parameter in the form of -`#[repr(packed(x))]`. If no value is given, as in `#[repr(packed)]`, then the -value is 1. The value must be a power of two from 1 up to -229. - -The `packed` modifier lowers the type's alignment to the specified value. If -the specified value is greater than the type's alignment without the -`packed` modifier, then the alignment and layout is unaffected. The alignments -of each field, for the purpose of positioning fields, is the smaller of the -specified packing and the alignment of the field's type. +For `packed`, if the specified alignment is greater than the type's alignment +without the `packed` modifier, then the alignment and layout is unaffected. +The alignments of each field, for the purpose of positioning fields, is the +smaller of the specified alignment and the alignment of the field's type. The `align` and `packed` modifiers cannot be applied on the same type and a -`packed` type cannot transitively contain another `align`ed type. `packed` may -only be applied to the default and `C` representations. +`packed` type cannot transitively contain another `align`ed type. `align` and +`packed` may only be applied to the [default] and [`C`] representations.
@@ -369,3 +358,7 @@ used with any other representation. [undefined behavior]: behavior-considered-undefined.html [27060]: https://github.com/rust-lang/rust/issues/27060 [`PhantomData`]: special-types-and-traits.html#phantomdatat +[Default]: #the-default-representation +[`C`]: #the-c-representation +[primitive representations]: #primitive-representations +[`transparent`]: #the-transparent-representation