@@ -1824,7 +1824,7 @@ fn foo(bytes: []u8) u32 {
1824
1824
}
1825
1825
{#code_end#}
1826
1826
{#header_close#}
1827
- {#see_also|C Pointers#}
1827
+ {#see_also|C Pointers|Pointers to Zero Bit Types #}
1828
1828
{#header_close#}
1829
1829
1830
1830
{#header_open|Slices#}
@@ -4464,9 +4464,20 @@ fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 {
4464
4464
{#header_close#}
4465
4465
{#header_close#}
4466
4466
4467
- {#header_open|void#}
4467
+ {#header_open|Zero Bit Types#}
4468
+ <p>For some types, {#link|@sizeOf#} is 0:</p>
4469
+ <ul>
4470
+ <li>{#link|void#}</li>
4471
+ <li>The {#link|Integers#} {#syntax#}u0{#endsyntax#} and {#syntax#}i0{#endsyntax#}.</li>
4472
+ <li>{#link|Arrays#} and {#link|Vectors#} with len 0, or with an element type that is a zero bit type.</li>
4473
+ <li>An {#link|enum#} with only 1 tag.</li>
4474
+ <li>An {#link|struct#} with all fields being zero bit types.</li>
4475
+ <li>A {#link|union#} with only 1 field which is a zero bit type.</li>
4476
+ <li>{#link|Pointers to Zero Bit Types#} are themselves zero bit types.</li>
4477
+ </ul>
4468
4478
<p>
4469
- {#syntax#}void{#endsyntax#} represents a type that has no value. Code that makes use of void values is
4479
+ These types can only ever have one possible value, and thus
4480
+ require 0 bits to represent. Code that makes use of these types is
4470
4481
not included in the final generated code:
4471
4482
</p>
4472
4483
{#code_begin|syntax#}
@@ -4476,15 +4487,17 @@ export fn entry() void {
4476
4487
x = y;
4477
4488
}
4478
4489
{#code_end#}
4479
- <p>When this turns into LLVM IR , there is no code generated in the body of {#syntax#}entry{#endsyntax#},
4480
- even in debug mode. For example, on x86_64:</p>
4490
+ <p>When this turns into machine code , there is no code generated in the
4491
+ body of {#syntax#}entry{#endsyntax#}, even in {#link|Debug#} mode. For example, on x86_64:</p>
4481
4492
<pre><code>0000000000000010 <entry>:
4482
4493
10: 55 push %rbp
4483
4494
11: 48 89 e5 mov %rsp,%rbp
4484
4495
14: 5d pop %rbp
4485
4496
15: c3 retq </code></pre>
4486
4497
<p>These assembly instructions do not have any code associated with the void values -
4487
4498
they only perform the function call prologue and epilog.</p>
4499
+
4500
+ {#header_open|void#}
4488
4501
<p>
4489
4502
{#syntax#}void{#endsyntax#} can be useful for instantiating generic types. For example, given a
4490
4503
{#syntax#}Map(Key, Value){#endsyntax#}, one can pass {#syntax#}void{#endsyntax#} for the {#syntax#}Value{#endsyntax#}
@@ -4556,6 +4569,38 @@ fn foo() i32 {
4556
4569
{#code_end#}
4557
4570
{#header_close#}
4558
4571
4572
+ {#header_open|Pointers to Zero Bit Types#}
4573
+ <p>Pointers to zero bit types also have zero bits. They always compare equal to each other:</p>
4574
+ {#code_begin|test#}
4575
+ const std = @import("std");
4576
+ const assert = std.debug.assert;
4577
+
4578
+ test "pointer to empty struct" {
4579
+ const Empty = struct {};
4580
+ var a = Empty{};
4581
+ var b = Empty{};
4582
+ var ptr_a = &a;
4583
+ var ptr_b = &b;
4584
+ comptime assert(ptr_a == ptr_b);
4585
+ }
4586
+ {#code_end#}
4587
+ <p>The type being pointed to can only ever be one value; therefore loads and stores are
4588
+ never generated. {#link|ptrToInt#} and {#link|intToPtr#} are not allowed:</p>
4589
+ {#code_begin|test_err#}
4590
+ const Empty = struct {};
4591
+
4592
+ test "@ptrToInt for pointer to zero bit type" {
4593
+ var a = Empty{};
4594
+ _ = @ptrToInt(&a);
4595
+ }
4596
+
4597
+ test "@intToPtr for pointer to zero bit type" {
4598
+ _ = @intToPtr(*Empty, 0x1);
4599
+ }
4600
+ {#code_end#}
4601
+ {#header_close#}
4602
+ {#header_close#}
4603
+
4559
4604
{#header_open|comptime#}
4560
4605
<p>
4561
4606
Zig places importance on the concept of whether an expression is known at compile-time.
0 commit comments