You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 are arranged in the order declared, from the least to the most significant bits of a backing integer.</li>
2231
-
<li>There is no padding between fields.</li>
2232
-
<li>The backing integer has the same bit width as the fields' total bit width.</li>
2233
-
<li>The backing integer is subject to the same rules as any integer, including {#link|alignment|Alignment#},
2234
-
having a maximum bit count of 65535, and the host endianness.
2235
-
On a big endian system, the first declared field will have the highest memory address, and on a little endian system, the lowest.
2236
-
</li>
2237
-
<li>Due to {#link|alignment|Alignment#}, the backing integer may require more memory that its bit width. {#link|@bitSizeOf|@bitSizeOf#} and {#link|@sizeOf|@sizeOf#} can interrogate the difference.</li>
2238
-
<li>Field access and assignment can be understood as shorthand for bitshifts on the backing integer.</li>
2239
-
<li>An {#link|integer|Integers#} field uses exactly as many bits as its bit width. For example, a {#syntax#}u5{#endsyntax#} will use 5 bits of the backing integer.</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>
2240
2241
<li>A {#link|bool|Primitive Types#} field uses exactly 1 bit.</li>
2241
2242
<li>An {#link|enum#} field uses exactly the bit width of its integer tag type.</li>
2242
2243
<li>A {#link|packed union#} field uses exactly the bit width of the union field with
2243
2244
the largest bit width.</li>
2244
-
<li>A {#syntax#}packed struct{#endsyntax#} field, when within a {#syntax#}packed struct{#endsyntax#}, uses exactly the bit width of its backing integer. For example,
2245
-
a {#syntax#}packed struct{#endsyntax#} field having backing integer {#syntax#}u17{#endsyntax#} uses 17 bits of its parent's backing integer.
2246
-
</li>
2247
-
<li>Packed structs support equality operators.</li>
2245
+
<li>A {#syntax#}packed struct{#endsyntax#} field uses the bits of its backing integer.</li>
2248
2246
</ul>
2249
2247
<p>
2250
2248
This means that a {#syntax#}packed struct{#endsyntax#} can participate
2251
2249
in a {#link|@bitCast#} or a {#link|@ptrCast#} to reinterpret memory.
2252
2250
This even works at {#link|comptime#}:
2253
2251
</p>
2254
2252
{#code|test_packed_structs.zig#}
2255
-
2256
2253
<p>
2257
-
The backing integer can be inferred or explicitly provided. When inferred, it will be unsigned. When explicitly provided, its bit width will be enforced at compile time to exactly match the total bit width of the fields:
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:
2258
2258
</p>
2259
2259
{#code|test_missized_packed_struct.zig#}
2260
2260
@@ -2296,17 +2296,18 @@ or
2296
2296
2297
2297
<p>
2298
2298
Equating packed structs results in a comparison of the backing integer,
2299
-
and only works for the `==` and `!=` operators.
2299
+
and only works for the {#syntax#}=={#endsyntax#} and {#syntax#}!={#endsyntax#} {#link|Operators#}.
2300
2300
</p>
2301
2301
{#code|test_packed_struct_equality.zig#}
2302
2302
2303
2303
<p>
2304
-
Packed structs can be used to interact with memory-mapped input-output (MMIO), which is
2305
-
common in embedded applications. A pointer of the correct alignment and address to a packed struct
2306
-
can be constructed to faciltiate manipulation of bit-packed registers without arduous bitshifting.
2307
-
2308
-
{#code|packed_struct_mmio.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.
0 commit comments