| ... | ... | @@ -1651,7 +1651,7 @@ fn foo(bytes: []u8) u32 { |
| 1651 | 1651 | <pre><code class="zig">@ptrCast(*u32, f32(12.34)).*</code></pre> |
| 1652 | 1652 | <p>Instead, use {#link|@bitCast#}: |
| 1653 | 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 | 1655 | {#see_also|Slices|Memory#} |
| 1656 | 1656 | {#header_close#} |
| 1657 | 1657 | {#header_close#} |
| ... | ... | @@ -3551,13 +3551,91 @@ const optional_value: ?i32 = null; |
| 3551 | 3551 | <p>TODO: ptrcast builtin</p> |
| 3552 | 3552 | <p>TODO: explain number literals vs concrete types</p> |
| 3553 | 3553 | {#header_close#} |
| 3554 | |
| 3554 | 3555 | {#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#} |
| 3560 | 3637 | {#header_close#} |
| 3638 | |
| 3561 | 3639 | {#header_open|this#} |
| 3562 | 3640 | <p>TODO: example of this referring to Self struct</p> |
| 3563 | 3641 | <p>TODO: example of this referring to recursion function</p> |