Exercise 19-1. Write a program that overflows a u8 using +=. Run it in Debug mode and observe the panic.
Exercise 19-1. Write a program that overflows a u8 using +=. Run it in Debug mode and observe the panic.
Exercise 19-2. Rewrite Exercise 19-1 using +%=. Verify that the value wraps to zero.
Exercise 19-3. Declare an array with three elements and intentionally access index 3. Observe the runtime behavior in Debug mode.
Exercise 19-4. Declare a variable with undefined, assign a value later, and print the result. Then remove the assignment and observe the behavior.
Exercise 19-5. Write a program that unwraps a null optional using .?. Rewrite it using if.
Exercise 19-6. Write a function that returns an error union. Handle the error once with catch and once with try.
Exercise 19-7. Use @addWithOverflow with two u16 values. Print both the wrapped result and the overflow flag.
Exercise 19-8. Create a u32, cast its pointer to *[4]u8, and print the bytes individually.
Exercise 19-9. Explain why the byte order from Exercise 19-8 depends on the target architecture.
Exercise 19-10. Replace a pointer reinterpretation with std.mem.readInt.
Exercise 19-11. Construct a pointer with @ptrFromInt. Explain why dereferencing it is dangerous unless the address is known to be valid.
Exercise 19-12. Create a *volatile u32 pointing to a fixed address. Explain why volatile accesses cannot be optimized away.
Exercise 19-13. Explain why volatile memory does not provide thread synchronization.
Exercise 19-14. Use @atomicRmw to implement a shared counter increment.
Exercise 19-15. Define a packed struct containing several bit fields that fit into one byte.
Exercise 19-16. Add an explicit backing integer type to the packed struct from Exercise 19-15.
Exercise 19-17. Define an extern struct representing a C structure with integer fields.
Exercise 19-18. Import stdio.h with @cImport and call puts.
Exercise 19-19. Write a Zig wrapper around a C-style function that returns integer status codes.
Exercise 19-20. Write a Zig callback function using callconv(.c).
Exercise 19-21. Explain the difference between:
structextern structand:
packed structExercise 19-22. Rewrite an index-based loop over an array as a direct for loop over the slice itself.
Exercise 19-23. Write a small hash function that intentionally uses wrapping arithmetic.
Exercise 19-24. Explain why ordinary arithmetic operators are usually safer than wrapping operators.
Exercise 19-25. Create a small module that isolates all unsafe pointer casts into one file.
Exercise 19-26. Describe three situations where pointer casts are appropriate and three where they should be avoided.
Exercise 19-27. Explain the difference between:
*T[*]Tand:
[]TExercise 19-28. Explain why a slice is generally safer than a many-item pointer.
Exercise 19-29. Build and run several exercises in:
| Mode | Command |
|---|---|
| Debug | zig build-exe file.zig |
| ReleaseSafe | zig build-exe -O ReleaseSafe file.zig |
| ReleaseFast | zig build-exe -O ReleaseFast file.zig |
Observe which safety checks remain enabled.
Exercise 19-30. Write a short summary explaining Zig’s approach to unsafe operations and undefined behavior.