aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Gauer <dave@ratfactor.com>2021-06-15 10:12:57 -0400
committerDave Gauer <dave@ratfactor.com>2021-06-15 10:12:57 -0400
commitda219d3c40dd2711cb1b144a8fd2f6ca4e86d159 (patch)
tree5e083e01b8d7f46c5a15fd9a927e44f52876cdc6
parent8dd9c1ddcb55b5a28f0dbec844a971daceef062e (diff)
downloadziglings-da219d3c40dd2711cb1b144a8fd2f6ca4e86d159.tar.gz
ziglings-da219d3c40dd2711cb1b144a8fd2f6ca4e86d159.tar.bz2
ziglings-da219d3c40dd2711cb1b144a8fd2f6ca4e86d159.tar.xz
ziglings-da219d3c40dd2711cb1b144a8fd2f6ca4e86d159.zip
added ub exploration to ex090
-rw-r--r--091_async8.zig20
-rw-r--r--exercises/090_async7.zig46
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.
+//