authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-18 12:02:30-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-18 12:02:30-04:00
log48985a7e684ff32eb5d419a89eac3b92c08c3ee9
tree3d7b43ab51b012bd85b2622a4f35fe6f95ca8fbd
parent8fd7cc11e167c0b23892d6f22841bb6856d0f499

langref: add docs for void

see #367

1 files changed, 84 insertions(+), 6 deletions(-)

doc/langref.html.in+84-6
...@@ -1651,7 +1651,7 @@ fn foo(bytes: []u8) u32 {...@@ -1651,7 +1651,7 @@ fn foo(bytes: []u8) u32 {
1651 <pre><code class="zig">@ptrCast(*u32, f32(12.34)).*</code></pre>1651 <pre><code class="zig">@ptrCast(*u32, f32(12.34)).*</code></pre>
1652 <p>Instead, use {#link|@bitCast#}:1652 <p>Instead, use {#link|@bitCast#}:
1653 <pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre>1653 <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>
1655 {#see_also|Slices|Memory#}1655 {#see_also|Slices|Memory#}
1656 {#header_close#}1656 {#header_close#}
1657 {#header_close#}1657 {#header_close#}
...@@ -3551,13 +3551,91 @@ const optional_value: ?i32 = null;...@@ -3551,13 +3551,91 @@ const optional_value: ?i32 = null;
3551 <p>TODO: ptrcast builtin</p>3551 <p>TODO: ptrcast builtin</p>
3552 <p>TODO: explain number literals vs concrete types</p>3552 <p>TODO: explain number literals vs concrete types</p>
3553 {#header_close#}3553 {#header_close#}
3554
3554 {#header_open|void#}3555 {#header_open|void#}
3555 <p>TODO: assigning void has no codegen</p>3556 <p>
3556 <p>TODO: hashmap with void becomes a set</p>3557 <code>void</code> represents a type that has no value. Code that makes use of void values is
3557 <p>TODO: difference between c_void and void</p>3558 not included in the final generated code:
3558 <p>TODO: void is the default return value of functions</p>3559 </p>
3559 <p>TODO: functions require assigning the return value</p>3560 {#code_begin|syntax#}
3561export 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#}
3582const std = @import("std");
3583const assert = std.debug.assert;
3584
3585test "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
3599fn hash_i32(x: i32) u32 {
3600 return @bitCast(u32, x);
3601}
3602
3603fn 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#}
3621test "ignoring expression value" {
3622 foo();
3623}
3624
3625fn 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#}
3631test "ignoring expression value" {
3632 foo();
3633}
3634
3635fn foo() void {}
3636 {#code_end#}
3560 {#header_close#}3637 {#header_close#}
3638
3561 {#header_open|this#}3639 {#header_open|this#}
3562 <p>TODO: example of this referring to Self struct</p>3640 <p>TODO: example of this referring to Self struct</p>
3563 <p>TODO: example of this referring to recursion function</p>3641 <p>TODO: example of this referring to recursion function</p>