| ... | ... | @@ -1649,6 +1649,7 @@ unwrapped == 1234{#endsyntax#}</pre> |
| 1649 | 1649 | <li>{#link|Floats#}</li> |
| 1650 | 1650 | <li>{#link|bool|Primitive Types#}</li> |
| 1651 | 1651 | <li>{#link|type|Primitive Types#}</li> |
| 1652 | <li>{#link|packed struct#}</li> |
| 1652 | 1653 | </ul> |
| 1653 | 1654 | </td> |
| 1654 | 1655 | <td> |
| ... | ... | @@ -2224,20 +2225,24 @@ or |
| 2224 | 2225 | |
| 2225 | 2226 | {#header_open|packed struct#} |
| 2226 | 2227 | <p> |
| 2227 | | Unlike normal structs, {#syntax#}packed{#endsyntax#} structs have guaranteed in-memory layout: |
| 2228 | {#syntax#}packed{#endsyntax#} structs, like {#syntax#}enum{#endsyntax#}, are based on the concept |
| 2229 | of interpreting integers differently. All packed structs have a <strong>backing integer</strong>, |
| 2230 | which is implicitly determined by the total bit count of fields, or explicitly specified. |
| 2231 | Packed structs have well-defined memory layout - exactly the same ABI as their backing integer. |
| 2232 | </p> |
| 2233 | <p> |
| 2234 | Each field of a packed struct is interpreted as a logical sequence of bits, arranged from |
| 2235 | least to most significant. Allowed field types: |
| 2228 | 2236 | </p> |
| 2229 | 2237 | <ul> |
| 2230 | | <li>Fields remain in the order declared, least to most significant.</li> |
| 2231 | | <li>There is no padding between fields.</li> |
| 2232 | | <li>Zig supports arbitrary width {#link|Integers#} and although normally, integers with fewer |
| 2233 | | than 8 bits will still use 1 byte of memory, in packed structs, they use |
| 2234 | | exactly their bit width. |
| 2235 | | </li> |
| 2236 | | <li>{#syntax#}bool{#endsyntax#} fields use exactly 1 bit.</li> |
| 2238 | <li>An {#link|integer|Integers#} field uses exactly as many bits as its |
| 2239 | bit width. For example, a {#syntax#}u5{#endsyntax#} will use 5 bits of |
| 2240 | the backing integer.</li> |
| 2241 | <li>A {#link|bool|Primitive Types#} field uses exactly 1 bit.</li> |
| 2237 | 2242 | <li>An {#link|enum#} field uses exactly the bit width of its integer tag type.</li> |
| 2238 | 2243 | <li>A {#link|packed union#} field uses exactly the bit width of the union field with |
| 2239 | 2244 | the largest bit width.</li> |
| 2240 | | <li>Packed structs support equality operators.</li> |
| 2245 | <li>A {#syntax#}packed struct{#endsyntax#} field uses the bits of its backing integer.</li> |
| 2241 | 2246 | </ul> |
| 2242 | 2247 | <p> |
| 2243 | 2248 | This means that a {#syntax#}packed struct{#endsyntax#} can participate |
| ... | ... | @@ -2245,10 +2250,11 @@ or |
| 2245 | 2250 | This even works at {#link|comptime#}: |
| 2246 | 2251 | </p> |
| 2247 | 2252 | {#code|test_packed_structs.zig#} |
| 2248 | | |
| 2249 | 2253 | <p> |
| 2250 | | The backing integer is inferred from the fields' total bit width. |
| 2251 | | Optionally, it can be explicitly provided and enforced at compile time: |
| 2254 | The backing integer can be inferred or explicitly provided. When |
| 2255 | inferred, it will be unsigned. When explicitly provided, its bit width |
| 2256 | will be enforced at compile time to exactly match the total bit width of |
| 2257 | the fields: |
| 2252 | 2258 | </p> |
| 2253 | 2259 | {#code|test_missized_packed_struct.zig#} |
| 2254 | 2260 | |
| ... | ... | @@ -2290,18 +2296,18 @@ or |
| 2290 | 2296 | |
| 2291 | 2297 | <p> |
| 2292 | 2298 | Equating packed structs results in a comparison of the backing integer, |
| 2293 | | and only works for the `==` and `!=` operators. |
| 2299 | and only works for the {#syntax#}=={#endsyntax#} and {#syntax#}!={#endsyntax#} {#link|Operators#}. |
| 2294 | 2300 | </p> |
| 2295 | 2301 | {#code|test_packed_struct_equality.zig#} |
| 2296 | 2302 | |
| 2297 | 2303 | <p> |
| 2298 | | Using packed structs with {#link|volatile#} is problematic, and may be a compile error in the future. |
| 2299 | | For details on this subscribe to |
| 2300 | | <a href="https://github.com/ziglang/zig/issues/1761">this issue</a>. |
| 2301 | | TODO update these docs with a recommendation on how to use packed structs with MMIO |
| 2302 | | (the use case for volatile packed structs) once this issue is resolved. |
| 2303 | | Don't worry, there will be a good solution for this use case in zig. |
| 2304 | Field access and assignment can be understood as shorthand for bitshifts |
| 2305 | on the backing integer. These operations are not {#link|atomic|Atomics#}, |
| 2306 | so beware using field access syntax when combined with memory-mapped |
| 2307 | input-output (MMIO). Instead of field access on {#link|volatile#} {#link|Pointers#}, |
| 2308 | construct a fully-formed new value first, then write that value to the volatile pointer. |
| 2304 | 2309 | </p> |
| 2310 | {#code|packed_struct_mmio.zig#} |
| 2305 | 2311 | {#header_close#} |
| 2306 | 2312 | |
| 2307 | 2313 | {#header_open|Struct Naming#} |