| ... | @@ -6665,6 +6665,8 @@ comptime { | ... | @@ -6665,6 +6665,8 @@ comptime { |
| 6665 | {#code_end#} | 6665 | {#code_end#} |
| 6666 | <p>At runtime:</p> | 6666 | <p>At runtime:</p> |
| 6667 | {#code_begin|exe_err#} | 6667 | {#code_begin|exe_err#} |
| | 6668 | const std = @import("std"); |
| | 6669 | |
| 6668 | const Set1 = error{ | 6670 | const Set1 = error{ |
| 6669 | A, | 6671 | A, |
| 6670 | B, | 6672 | B, |
| ... | @@ -6674,10 +6676,11 @@ const Set2 = error{ | ... | @@ -6674,10 +6676,11 @@ const Set2 = error{ |
| 6674 | C, | 6676 | C, |
| 6675 | }; | 6677 | }; |
| 6676 | pub fn main() void { | 6678 | pub fn main() void { |
| 6677 | _ = foo(Set1.B); | 6679 | foo(Set1.B); |
| 6678 | } | 6680 | } |
| 6679 | fn foo(set1: Set1) Set2 { | 6681 | fn foo(set1: Set1) void { |
| 6680 | return @errSetCast(Set2, set1); | 6682 | const x = @errSetCast(Set2, set1); |
| | 6683 | std.debug.warn("value: {}\n", x); |
| 6681 | } | 6684 | } |
| 6682 | {#code_end#} | 6685 | {#code_end#} |
| 6683 | {#header_close#} | 6686 | {#header_close#} |
| ... | @@ -6705,7 +6708,84 @@ fn foo(bytes: []u8) u32 { | ... | @@ -6705,7 +6708,84 @@ fn foo(bytes: []u8) u32 { |
| 6705 | {#code_end#} | 6708 | {#code_end#} |
| 6706 | {#header_close#} | 6709 | {#header_close#} |
| 6707 | {#header_open|Wrong Union Field Access#} | 6710 | {#header_open|Wrong Union Field Access#} |
| 6708 | <p>TODO</p> | 6711 | <p>At compile-time:</p> |
| | 6712 | {#code_begin|test_err|accessing union field 'float' while field 'int' is set#} |
| | 6713 | comptime { |
| | 6714 | var f = Foo{ .int = 42 }; |
| | 6715 | f.float = 12.34; |
| | 6716 | } |
| | 6717 | |
| | 6718 | const Foo = union { |
| | 6719 | float: f32, |
| | 6720 | int: u32, |
| | 6721 | }; |
| | 6722 | {#code_end#} |
| | 6723 | <p>At runtime:</p> |
| | 6724 | {#code_begin|exe_err#} |
| | 6725 | const std = @import("std"); |
| | 6726 | |
| | 6727 | const Foo = union { |
| | 6728 | float: f32, |
| | 6729 | int: u32, |
| | 6730 | }; |
| | 6731 | |
| | 6732 | pub fn main() void { |
| | 6733 | var f = Foo{ .int = 42 }; |
| | 6734 | bar(&f); |
| | 6735 | } |
| | 6736 | |
| | 6737 | fn bar(f: *Foo) void { |
| | 6738 | f.float = 12.34; |
| | 6739 | std.debug.warn("value: {}\n", f.float); |
| | 6740 | } |
| | 6741 | {#code_end#} |
| | 6742 | <p> |
| | 6743 | This safety is not available for <code>extern</code> or <code>packed</code> unions. |
| | 6744 | </p> |
| | 6745 | <p> |
| | 6746 | To change the active field of a union, assign the entire union, like this: |
| | 6747 | </p> |
| | 6748 | {#code_begin|exe#} |
| | 6749 | const std = @import("std"); |
| | 6750 | |
| | 6751 | const Foo = union { |
| | 6752 | float: f32, |
| | 6753 | int: u32, |
| | 6754 | }; |
| | 6755 | |
| | 6756 | pub fn main() void { |
| | 6757 | var f = Foo{ .int = 42 }; |
| | 6758 | bar(&f); |
| | 6759 | } |
| | 6760 | |
| | 6761 | fn bar(f: *Foo) void { |
| | 6762 | f.* = Foo{ .float = 12.34 }; |
| | 6763 | std.debug.warn("value: {}\n", f.float); |
| | 6764 | } |
| | 6765 | {#code_end#} |
| | 6766 | <p> |
| | 6767 | To change the active field of a union when a meaningful value for the field is not known, |
| | 6768 | use {#link|undefined#}, like this: |
| | 6769 | </p> |
| | 6770 | {#code_begin|exe#} |
| | 6771 | const std = @import("std"); |
| | 6772 | |
| | 6773 | const Foo = union { |
| | 6774 | float: f32, |
| | 6775 | int: u32, |
| | 6776 | }; |
| | 6777 | |
| | 6778 | pub fn main() void { |
| | 6779 | var f = Foo{ .int = 42 }; |
| | 6780 | f = Foo{ .float = undefined }; |
| | 6781 | bar(&f); |
| | 6782 | std.debug.warn("value: {}\n", f.float); |
| | 6783 | } |
| | 6784 | |
| | 6785 | fn bar(f: *Foo) void { |
| | 6786 | f.float = 12.34; |
| | 6787 | } |
| | 6788 | {#code_end#} |
| 6709 | {#header_close#} | 6789 | {#header_close#} |
| 6710 | | 6790 | |
| 6711 | {#header_open|Out of Bounds Float To Integer Cast#} | 6791 | {#header_open|Out of Bounds Float To Integer Cast#} |