From 58f5d8e33c2eaa0cbfbfcc84925767a7a06ae908 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 1 Aug 2019 19:06:07 +0200 Subject: [PATCH 1/5] ASCII art for structs --- reference/src/layout/structs-and-tuples.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/reference/src/layout/structs-and-tuples.md b/reference/src/layout/structs-and-tuples.md index 652252e9..b89e35dd 100644 --- a/reference/src/layout/structs-and-tuples.md +++ b/reference/src/layout/structs-and-tuples.md @@ -72,7 +72,18 @@ struct Foo { (In fact, one may use such field names in patterns or in accessor expressions like `foo.0`.) -Structs can have various `#[repr]` flags that influence their layout: +When layout out a struct, the compiler in particular has to decide how the +fields of the struct are arranged, which can be visualized as follows: +``` +[ <--> [field 1] <-----> [field 2] <-> [ field 3 ] <--> ] +``` +The individual fields are blocks of fixed size (determined by the field's +layout). The compiler freely picks an order for the fields to be in (this does +not have to be the order of declaration in the source), and it picks the gaps +between the fields (under some constraints, such as alignment). + +What exactly the compiler does, as well as other aspects of layout beyond size +and field offset, can be controlled by a `#[repr]` attribute: - `#[repr(Rust)]` -- the default. - `#[repr(C)]` -- request C compatibility From fee3cd469574a057ab8520b8a55f1ba373ae3c9f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 2 Aug 2019 14:16:33 +0200 Subject: [PATCH 2/5] this is not code --- reference/src/layout/structs-and-tuples.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/src/layout/structs-and-tuples.md b/reference/src/layout/structs-and-tuples.md index b89e35dd..1715b64b 100644 --- a/reference/src/layout/structs-and-tuples.md +++ b/reference/src/layout/structs-and-tuples.md @@ -74,7 +74,7 @@ expressions like `foo.0`.) When layout out a struct, the compiler in particular has to decide how the fields of the struct are arranged, which can be visualized as follows: -``` +```text [ <--> [field 1] <-----> [field 2] <-> [ field 3 ] <--> ] ``` The individual fields are blocks of fixed size (determined by the field's From a6ce041ed69733e44820281c7852980424d4d58a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 15 Aug 2019 13:09:58 +0200 Subject: [PATCH 3/5] talk about degrees of freedom --- reference/src/layout/structs-and-tuples.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/reference/src/layout/structs-and-tuples.md b/reference/src/layout/structs-and-tuples.md index 1715b64b..4ecc06ed 100644 --- a/reference/src/layout/structs-and-tuples.md +++ b/reference/src/layout/structs-and-tuples.md @@ -72,18 +72,23 @@ struct Foo { (In fact, one may use such field names in patterns or in accessor expressions like `foo.0`.) -When layout out a struct, the compiler in particular has to decide how the -fields of the struct are arranged, which can be visualized as follows: +The degrees of freedom the compiler has when computing the layout of a struct or +tuple is to determine the order of the fields, and the "gaps" before, between, +and after the fields. The layout of these fields themselves is already entirely +determined by their types, and since we intend to allow creating references to +fields (`&s.f1`), structs do not have any wiggle-room there. + +This can be visualized as follows: ```text -[ <--> [field 1] <-----> [field 2] <-> [ field 3 ] <--> ] +[ <--> [field 3] <-----> [field 1] <-> [ field 2 ] <--> ] ``` -The individual fields are blocks of fixed size (determined by the field's +Here, the individual fields are blocks of fixed size (determined by the field's layout). The compiler freely picks an order for the fields to be in (this does not have to be the order of declaration in the source), and it picks the gaps between the fields (under some constraints, such as alignment). -What exactly the compiler does, as well as other aspects of layout beyond size -and field offset, can be controlled by a `#[repr]` attribute: +How exactly the compiler picks order and gaps, as well as other aspects of +layout beyond size and field offset, can be controlled by a `#[repr]` attribute: - `#[repr(Rust)]` -- the default. - `#[repr(C)]` -- request C compatibility From 2f6167159a8ac4e8529f8b338ac504e42ef99ef9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 15 Aug 2019 13:13:21 +0200 Subject: [PATCH 4/5] call it padding --- reference/src/layout/structs-and-tuples.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/reference/src/layout/structs-and-tuples.md b/reference/src/layout/structs-and-tuples.md index 4ecc06ed..149fed67 100644 --- a/reference/src/layout/structs-and-tuples.md +++ b/reference/src/layout/structs-and-tuples.md @@ -73,10 +73,11 @@ struct Foo { expressions like `foo.0`.) The degrees of freedom the compiler has when computing the layout of a struct or -tuple is to determine the order of the fields, and the "gaps" before, between, -and after the fields. The layout of these fields themselves is already entirely -determined by their types, and since we intend to allow creating references to -fields (`&s.f1`), structs do not have any wiggle-room there. +tuple is to determine the order of the fields, and the "gaps" (often called +*padding*) before, between, and after the fields. The layout of these fields +themselves is already entirely determined by their types, and since we intend to +allow creating references to fields (`&s.f1`), structs do not have any +wiggle-room there. This can be visualized as follows: ```text From cdf125919ebe5588d7e939c910a2e8d31d37cddb Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 27 Aug 2019 18:00:28 +0200 Subject: [PATCH 5/5] Apply suggestions from code review Co-Authored-By: gnzlbg --- reference/src/layout/structs-and-tuples.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reference/src/layout/structs-and-tuples.md b/reference/src/layout/structs-and-tuples.md index 149fed67..5e306739 100644 --- a/reference/src/layout/structs-and-tuples.md +++ b/reference/src/layout/structs-and-tuples.md @@ -83,6 +83,8 @@ This can be visualized as follows: ```text [ <--> [field 3] <-----> [field 1] <-> [ field 2 ] <--> ] ``` +**Figure 1** (struct-field layout): The `<-...->` and `[ ... ]` denote the differently-sized gaps and fields, respectively. + Here, the individual fields are blocks of fixed size (determined by the field's layout). The compiler freely picks an order for the fields to be in (this does not have to be the order of declaration in the source), and it picks the gaps