diff options
author | Dave Gauer <dave@ratfactor.com> | 2021-06-15 10:12:57 -0400 |
---|---|---|
committer | Dave Gauer <dave@ratfactor.com> | 2021-06-15 10:12:57 -0400 |
commit | da219d3c40dd2711cb1b144a8fd2f6ca4e86d159 (patch) | |
tree | 5e083e01b8d7f46c5a15fd9a927e44f52876cdc6 | |
parent | 8dd9c1ddcb55b5a28f0dbec844a971daceef062e (diff) | |
download | ziglings-da219d3c40dd2711cb1b144a8fd2f6ca4e86d159.tar.gz ziglings-da219d3c40dd2711cb1b144a8fd2f6ca4e86d159.tar.bz2 ziglings-da219d3c40dd2711cb1b144a8fd2f6ca4e86d159.tar.xz ziglings-da219d3c40dd2711cb1b144a8fd2f6ca4e86d159.zip |
added ub exploration to ex090
-rw-r--r-- | 091_async8.zig | 20 | ||||
-rw-r--r-- | exercises/090_async7.zig | 46 |
2 files changed, 65 insertions, 1 deletions
diff --git a/091_async8.zig b/091_async8.zig new file mode 100644 index 0000000..5f9e19b --- /dev/null +++ b/091_async8.zig @@ -0,0 +1,20 @@ +// +// Perhaps you have been wondering why we have always called 'suspend' +// with an expression in the form of an empty block: +// +// suspend {} +// +// well, +// +const print = @import("std").debug.print; + +pub fn main() void { + + var my_beef = getBeef(0); + + print("beef? {X}!\n", .{my_beef}); +} + +fn getBeef(input: u32) u32 { + suspend {} +} diff --git a/exercises/090_async7.zig b/exercises/090_async7.zig index 89113bd..0214f34 100644 --- a/exercises/090_async7.zig +++ b/exercises/090_async7.zig @@ -35,9 +35,53 @@ pub fn main() void { } fn getBeef(input: u32) u32 { - if (input > 0xDEAD) { + if (input == 0xDEAD) { suspend {} } return 0xBEEF; } +// +// Going Deeper Into... +// ...uNdeFiNEd beHAVi0r! +// +// We haven't discussed it yet, but runtime "safety" features +// require some extra instructions in your compiled program. +// Most of the time, you're going to want to keep these in. +// +// But in some programs, when data integrity is less important +// than raw speed (some games, for example), you can compile +// without these safety features. +// +// Instead of a safe panic when something goes wrong, your +// program will now exhibit Undefined Behavior (UB), which simply +// means that the Zig language does not (cannot) define what will +// happen. The best case is that it will crash, but in the worst +// case, it will continue to run with the wrong results and +// corrupt your data or expose you to security risks. +// +// This program is a great way to explore UB. Once you get it +// working, try calling the getBeef() function with the value +// 0xDEAD so that it will invoke the 'suspend' keyword: +// +// getBeef(0xDEAD) +// +// Now when you run the program, it will panic and give you a +// nice stack trace to help debug the problem. +// +// zig run exercises/090_async7.zig +// thread 328 panic: async function called... +// ... +// +// But see what happens when you turn off safety checks by using +// ReleaseFast mode: +// +// zig run -O ReleaseFast exercises/090_async7.zig +// beef? 0! +// +// This is the wrong result. On your computer, you may get a +// different answer or it might crash! What exactly will happen +// is UNDEFINED. Your computer is now like a wild animal, +// reacting to bits and bytes of raw memory with the base +// instincts of the CPU. It is both terrifying and exhilarating. +// |