A hands-on comparison between Rust and C at the assembly level. Explore how zero-cost abstractions, ownership models, and type systems affect real machine code.
πΈ Want the full story with live GDB debugging sessions, assembly screenshots, and real-world commentary? π Read the complete article here
(Includes all the annotated GDB screenshots, performance commentary, and the story behind the code.)
π Compare Rust and C in terms of memory safety, pointer behavior, runtime checks, and compiler optimizations β all at the assembly level.
This project demonstrates fundamental differences between Rust and C by analyzing their generated assembly code across critical areas:
- Memory Management: Ownership vs Manual Control
- Safety Guarantees: Compile-time vs Runtime Checks
- Abstraction Cost: Zero-cost vs Manual Overhead
- Concurrency Models: Type-safe vs Raw Synchronization
- Pointer Semantics: Rich Types vs Raw Pointers
src/
βββ rust/
β βββ ownership.rs # Automatic memory management
β βββ immutable.rs # Immutability and optimization
β βββ bounds_check.rs # Array bounds safety
β βββ generics.rs # Type-safe generics
β βββ threading.rs # Thread-safe concurrency
β βββ unsafe_hw.rs # Hardware register access
β βββ recursion.rs # Function call optimization
β βββ pointer.rs # Comprehensive pointer types
βββ c/
βββ ownership.c # Manual memory management
βββ immutable.c # const hints and optimization
βββ bounds_check.c # Unchecked array access
βββ generics.c # Macro-based generics
βββ threading.c # pthread synchronization
βββ unsafe_hw.c # Direct hardware access
βββ recursion.c # Function call patterns
βββ pointer.c # Traditional pointer usage
- Rust: Automatic
drop_in_place, no use-after-free - C: Manual
malloc/free, prone to leaks and UAF
- Rust: Immutable by default β better inlining & optimization
- C:
constas hint only, mutable by default
- Rust: Conditional jumps to panic handlers
- C: No checks, buffer overflows = undefined behavior
- Rust: Monomorphization, type-safe
- C: Preprocessor macros, type-unsafe
- Rust:
Send/Synctraits at compile-time - C: Manual
pthread_mutex, error-prone
- Rust: Isolated via
unsafeblocks - C: All access treated equally, no guardrails
- Rust: Same optimizations as C + stack checks
- C: Compiler-dependent optimizations, no overflow checks
- Rust: Fine-grained references, ownership enforced
- C: One-size-fits-all pointer, no lifetime tracking
make all # Build all examples and generate assembly
make compare # Compare Rust and C outputs
make analyze_ptr # Analyze specific pointer comparisonmake rust_asm # Rust-only builds
make c_asm # C-only builds
make run_rust # Run all Rust examples
make run_c # Run all C examples
make diff_bounds # Compare bounds checking- Rust:
target/release/deps/example-*.s - C:
target/example.s
You can inspect these outputs in your disassembler or objdump -d.
| Aspect | Rust | C |
|---|---|---|
| Memory Safety | Automatic drop_in_place |
Manual malloc / free |
| Bounds Checking | Jump to panic handlers on violation | No checks, UB |
| Pointer Semantics | Rich pointer types & lifetimes | Raw pointers only |
| Thread Safety | Compile-time checked with traits | Manual, prone to races |
| Optimization | Zero-cost abstraction via LLVM | Manual hints, limited inlining |
&T // Immutable reference
&mut T // Exclusive mutable reference
Box<T> // Heap allocation
Rc<T> // Single-threaded ref counting
Arc<T> // Thread-safe atomic ref counting
*const T, *mut T // Raw pointers (unsafe)
Pin<Box<T>> // Prevents movement (pinned heap)const int *ptr // const pointer
int *ptr // mutable pointer
malloc/free // manual heap allocation
volatile int * // volatile access
int *alias // no ownership model- Zero-Cost Abstractions: Rustβs safety features often compile to identical assembly as hand-optimized C
- Aggressive Optimization: Rustβs ownership and mutability rules allow more predictable optimizations
- Minimal Runtime Cost: Bounds checks and drops are lightweight
- Better Safety by Design: Common C pitfalls (use-after-free, race conditions) are structurally impossible in Rust
Perfect for:
- π Security Researchers
- βοΈ Systems Engineers
- π§΅ Compiler Developers
- π§ Advanced Learners of Low-Level Programming
# Prerequisites
rustup install stable
sudo dnf install gcc make -y
# Build and analyze
make allRust delivers memory and thread safety without sacrificing performance. This project proves it β one assembly line at a time.
The code in this repo is explained step-by-step in my in-depth article:
π Rust vs C Assembly: Panic or Segfault? (with GDB analysis)
- Complete walkthroughs for every function
- Assembly screenshots from GDB sessions
- Real-world systems programming insights
For questions or in-depth discussion, feel free to comment on the blog, or reach out via LinkedIn.