@@ -39,11 +39,56 @@ to obtain a pointer to any field, and vice versa.
39
39
[ 6.5.8.5 ] : http://port70.net/~nsz/c/c11/n1570.html#6.5.8p5
40
40
[ 6.7.2.1.16 ] : http://port70.net/~nsz/c/c11/n1570.html#6.7.2.1p16
41
41
42
- Since all fields are at offset 0, this implies that ` repr(C) ` unions do not have
43
- padding before or in-between their fields. They can, however, have trailing
44
- padding (see next example).
42
+ #### Padding
45
43
46
- Union fields of zero-size participate in the layout computation of the union. For example:
44
+ Since all fields are at offset 0, ` repr(C) ` unions do not have padding before
45
+ their fields. They can, however, have trailing padding, to make sure the size is
46
+ a multiple of the alignment:
47
+
48
+ ``` rust
49
+ # use std :: mem :: {size_of, align_of};
50
+ #[repr(C , align(2))]
51
+ union U { x : u8 }
52
+ # fn main () {
53
+ // The repr(align) attribute raises the alignment requirement of U to 2
54
+ assert_eq! (align_of :: <U >(), 2 );
55
+ // This introduces trailing padding, raising the union size to 2
56
+ assert_eq! (size_of :: <U >(), 2 );
57
+ # }
58
+ ``**
59
+
60
+ * * Note ** : there is no room between fields for padding , so `repr (C )` unions can
61
+ only have trailing padding .
62
+
63
+ The bit `i ` of a `repr (C )` union is a padding bit if the bit `i ` of each of its
64
+ fields is a padding bit or trailing padding . That is :
65
+
66
+ ```rust
67
+ #[repr(C )]
68
+ union U { x : (u8 , u16 ) }
69
+ ```
70
+
71
+ The byte at offset 1 of ` U ` is a padding byte.
72
+
73
+ #### Zero-sized fields
74
+
75
+ If a ` #[repr(C)] ` union contains a field of zero-size, that field does not
76
+ occupy space in the union. For example:
77
+
78
+ ``` rust
79
+ # use std :: mem :: {size_of, align_of};
80
+ #[repr(C )]
81
+ union U {
82
+ x : u8 ,
83
+ y : (),
84
+ }
85
+ # fn main () {
86
+ assert_eq! (size_of :: <U >(), 1 );
87
+ # }
88
+ ```
89
+
90
+ The field does, however, participate in the layout computation of the union. For
91
+ example:
47
92
48
93
``` rust
49
94
# use std :: mem :: {size_of, align_of};
@@ -60,12 +105,6 @@ assert_eq!(size_of::<U>(), 2);
60
105
# }
61
106
```
62
107
63
- > ** NOTE** : U is larger than its largest field, and has therefore 1 byte of
64
- > trailing padding.
65
-
66
108
This handling of zero-sized types is equivalent to the handling of zero-sized
67
109
types in struct fields, and matches the behavior of GCC and Clang for unions in
68
110
C when zero-sized types are allowed via their language extensions.
69
-
70
- The bit ` i ` of a ` repr(C) ` union is a padding bit if the bit ` i ` of each of its
71
- fields is a padding bit or trailing padding.
0 commit comments