Skip to content

Commit 48985a7

Browse files
committedJun 18, 2018
langref: add docs for void
see #367
·
0.15.20.3.0
1 parent 8fd7cc1 commit 48985a7

File tree

1 file changed

+84
-6
lines changed

1 file changed

+84
-6
lines changed
 

‎doc/langref.html.in‎

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1651,7 +1651,7 @@ fn foo(bytes: []u8) u32 {
16511651
<pre><code class="zig">@ptrCast(*u32, f32(12.34)).*</code></pre>
16521652
<p>Instead, use {#link|@bitCast#}:
16531653
<pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre>
1654-
<p>As an added benefit, the <code>@bitcast</code> version works at compile-time.</p>
1654+
<p>As an added benefit, the <code>@bitCast</code> version works at compile-time.</p>
16551655
{#see_also|Slices|Memory#}
16561656
{#header_close#}
16571657
{#header_close#}
@@ -3551,13 +3551,91 @@ const optional_value: ?i32 = null;
35513551
<p>TODO: ptrcast builtin</p>
35523552
<p>TODO: explain number literals vs concrete types</p>
35533553
{#header_close#}
3554+
35543555
{#header_open|void#}
3555-
<p>TODO: assigning void has no codegen</p>
3556-
<p>TODO: hashmap with void becomes a set</p>
3557-
<p>TODO: difference between c_void and void</p>
3558-
<p>TODO: void is the default return value of functions</p>
3559-
<p>TODO: functions require assigning the return value</p>
3556+
<p>
3557+
<code>void</code> represents a type that has no value. Code that makes use of void values is
3558+
not included in the final generated code:
3559+
</p>
3560+
{#code_begin|syntax#}
3561+
export fn entry() void {
3562+
var x: void = {};
3563+
var y: void = {};
3564+
x = y;
3565+
}
3566+
{#code_end#}
3567+
<p>When this turns into LLVM IR, there is no code generated in the body of <code>entry</code>,
3568+
even in debug mode. For example, on x86_64:</p>
3569+
<pre><code>0000000000000010 &lt;entry&gt;:
3570+
10: 55 push %rbp
3571+
11: 48 89 e5 mov %rsp,%rbp
3572+
14: 5d pop %rbp
3573+
15: c3 retq </code></pre>
3574+
<p>These assembly instructions do not have any code associated with the void values -
3575+
they only perform the function call prologue and epilog.</p>
3576+
<p>
3577+
<code>void</code> can be useful for instantiating generic types. For example, given a
3578+
<code>Map(Key, Value)</code>, one can pass <code>void</code> for the <code>Value</code>
3579+
type to make it into a <code>Set</code>:
3580+
</p>
3581+
{#code_begin|test#}
3582+
const std = @import("std");
3583+
const assert = std.debug.assert;
3584+
3585+
test "turn HashMap into a set with void" {
3586+
var map = std.HashMap(i32, void, hash_i32, eql_i32).init(std.debug.global_allocator);
3587+
defer map.deinit();
3588+
3589+
_ = try map.put(1, {});
3590+
_ = try map.put(2, {});
3591+
3592+
assert(map.contains(2));
3593+
assert(!map.contains(3));
3594+
3595+
_ = map.remove(2);
3596+
assert(!map.contains(2));
3597+
}
3598+
3599+
fn hash_i32(x: i32) u32 {
3600+
return @bitCast(u32, x);
3601+
}
3602+
3603+
fn eql_i32(a: i32, b: i32) bool {
3604+
return a == b;
3605+
}
3606+
{#code_end#}
3607+
<p>Note that this is different than using a dummy value for the hash map value.
3608+
By using <code>void</code> as the type of the value, the hash map entry type has no value field, and
3609+
thus the hash map takes up less space. Further, all the code that deals with storing and loading the
3610+
value is deleted, as seen above.
3611+
</p>
3612+
<p>
3613+
<code>void</code> is distinct from <code>c_void</code>, which is defined like this:
3614+
<code>pub const c_void = @OpaqueType();</code>.
3615+
<code>void</code> has a known size of 0 bytes, and <code>c_void</code> has an unknown, but non-zero, size.
3616+
</p>
3617+
<p>
3618+
Expressions of type <code>void</code> are the only ones whose value can be ignored. For example:
3619+
</p>
3620+
{#code_begin|test_err|expression value is ignored#}
3621+
test "ignoring expression value" {
3622+
foo();
3623+
}
3624+
3625+
fn foo() i32 {
3626+
return 1234;
3627+
}
3628+
{#code_end#}
3629+
<p>However, if the expression has type <code>void</code>:</p>
3630+
{#code_begin|test#}
3631+
test "ignoring expression value" {
3632+
foo();
3633+
}
3634+
3635+
fn foo() void {}
3636+
{#code_end#}
35603637
{#header_close#}
3638+
35613639
{#header_open|this#}
35623640
<p>TODO: example of this referring to Self struct</p>
35633641
<p>TODO: example of this referring to recursion function</p>

0 commit comments

Comments
 (0)
Please sign in to comment.