Raw & Unsafe
Advanced Topic
This section covers low-level operations that bypass Zith's safety guarantees. Only use these when absolutely necessary and when you fully understand the implications.
What is "Raw & Unsafe"?
Zith's safety model handles 95% of use cases. The raw and unsafe features are reserved for situations where you need:
- FFI (Foreign Function Interface) - Calling C libraries directly
- Raw pointer arithmetic - Custom memory layouts and allocators
- Inline assembly - Platform-specific optimizations
- Union field access - Type punning scenarios
- Custom allocators - Building your own memory management
Key Concepts
unsafe Blocks
Code inside an unsafe block bypasses Zith's safety checks:
unsafe {
// All code here bypasses safety checks
let ptr: *mut u8 = cast_to_ptr(0x1000);
*ptr = 42; // Direct memory write
}
Raw Pointers
Raw pointers (*const T and *mut T) give you direct memory access without compiler guarantees:
let value: i32 = 100;
// Immutable raw pointer
let imm_ptr: *const i32 = &value;
// Mutable raw pointer (requires unsafe)
let mut_ptr: *mut i32 = unsafe { addr_of_mut!(value) };
When to Use Raw & Unsafe
✅ Appropriate uses:
- Writing FFI bindings for C libraries
- Implementing custom allocators or data structures
- Performance-critical code with proven safety
- Inline assembly for hardware access
❌ Avoid when:
- Safe Zith constructs would work
- You're not certain about memory invariants
- The code will be frequently modified
- Safety can be guaranteed at runtime instead
Topics in This Section
| Topic | Description |
|---|---|
| How to Use | Best practices for organizing raw/unsafe code |
| Traits | Advanced trait usage with raw types |
| Generics Deep Dive | Complex generic patterns |
| Metaprogramming | Code generation techniques |
| Macros | Template and macro systems |
| Data Structures | Building custom data structures |
| Unsafe Operations | Detailed unsafe block usage |
| Raw Pointers | Complete raw pointer guide |
Safety Guidelines
- Minimize unsafe scope - Keep
unsafe {}blocks as small as possible - Document invariants - Explain why the unsafe code is safe
- Add runtime checks - Validate inputs before entering unsafe blocks
- Write tests - Especially for unsafe code paths
- Review carefully - Unsafe code requires extra scrutiny
Example: Safe Wrapper Around Unsafe Code
// Good: Small unsafe block with validation
fn get_element(arr: &[i32], index: usize): Option<i32> {
if index >= arr.len() {
return None;
}
unsafe {
Some(*arr.as_ptr().add(index))
}
}
Next Steps
- Learn how to use raw and unsafe features responsibly
- Dive into raw pointers for memory manipulation
- Understand unsafe operations in detail
Remember
With great power comes great responsibility. Always prefer safe Zith constructs when possible.