Skip to content

Exercises

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:

struct
extern struct

and:

packed struct

Exercise 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
[*]T

and:

[]T

Exercise 19-28. Explain why a slice is generally safer than a many-item pointer.

Exercise 19-29. Build and run several exercises in:

ModeCommand
Debugzig build-exe file.zig
ReleaseSafezig build-exe -O ReleaseSafe file.zig
ReleaseFastzig 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.