authorgravatar for kj4tmp@gmail.comkj4tmp <kj4tmp@gmail.com> 2024-10-18 00:52:56-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-04-15 19:17:07-07:00
loga8621731ec9726288614c8c1b88ae8293ebbf606
tree0c36d8885f44763307b7c61763e55f28892e4154
parentae38fc6a50dfcece964d7d19d9e35ac5dc583daa

langref: packed struct documentation


2 files changed, 34 insertions(+), 13 deletions(-)

doc/langref.html.in+18-13
......@@ -2227,16 +2227,23 @@ or
22272227 Unlike normal structs, {#syntax#}packed{#endsyntax#} structs have guaranteed in-memory layout:
22282228 </p>
22292229 <ul>
2230 <li>Fields remain in the order declared, least to most significant.</li>
2230 <li>Fields are arranged in the order declared, from the least to the most significant bits of a backing integer.</li>
22312231 <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.
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.
22352236 </li>
2236 <li>{#syntax#}bool{#endsyntax#} fields use exactly 1 bit.</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>
2240 <li>A {#link|bool|Primitive Types#} field uses exactly 1 bit.</li>
22372241 <li>An {#link|enum#} field uses exactly the bit width of its integer tag type.</li>
22382242 <li>A {#link|packed union#} field uses exactly the bit width of the union field with
22392243 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>
22402247 <li>Packed structs support equality operators.</li>
22412248 </ul>
22422249 <p>
......@@ -2247,8 +2254,7 @@ or
22472254 {#code|test_packed_structs.zig#}
22482255
22492256 <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:
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:
22522258 </p>
22532259 {#code|test_missized_packed_struct.zig#}
22542260
......@@ -2295,12 +2301,11 @@ or
22952301 {#code|test_packed_struct_equality.zig#}
22962302
22972303 <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 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#}
23042309 </p>
23052310 {#header_close#}
23062311
doc/langref/packed_struct_mmio.zig created+16
......@@ -0,0 +1,16 @@
1pub const GPIORegister = packed struct(u8) {
2 GPIO0: bool,
3 GPIO1: bool,
4 GPIO2: bool,
5 GPIO3: bool,
6 _reserved: u4 = 0,
7};
8
9/// Write a new state to the memory-mapped IO.
10pub fn writeToGPIO(new_states: GPIORegister) void {
11 const gpio_register_address = 0x0123;
12 const raw_ptr: *align(1) volatile GPIORegister = @ptrFromInt(gpio_register_address);
13 raw_ptr.* = new_states;
14}
15
16// syntax