Joint SRUG+NWCPP
2025.07 Meetup
-
Code of Conduct
-
NWCPP Website
http://www.nwcpp.org/
-
SRUG Discord:
https://discord.gg/4pDnjgaEV6
-
Slides:
https://slides.com/u007d
Upcoming C++/Rust Meetups
-
THIS is our Final Meetup at the MSFT Reactor
-
In search of a new home for Aug 21 (3rd Thu)
After-Meet Gathering
All are invited to gather tonight at
Red Robin
Joint Gathering!
Language Panel Presentation
Panel Introductions
Donna Smith
Cpp2
Theodore "Ted" Neward
C#, Mojo
Walter Bright
D
Dread Pirate Williamson
Swift
Lloyd Moore
C++
Brad Gibson
Rust
Donna Smith
Cpp2








Dread Pirate Williamson
Swift









Theodore "Ted" Neward
C#













Theodore "Ted" Neward
Mojo











Walter Bright
D
Language History
Who: Created by Walter Bright
What: The D Programming Language
Where: In my office
When: Started in 1999, release 1.0 in 2007
Why: Having developed a C and standard compliant C++ compiler, there was a
large opportunity to learn from those languages and create a much
better language.
How: Initially implemented using a "C with Classes" style code, then converted
the entire implementation in D. The community appeared and greatly
expanded the D ecosystem.
Status: Mature production compilers DMD, gnu based GDC, and LLVM based
LDC Update
Schedule: Generally when we feel there's enough to justify a new release Standards Body: The D Language Foundation
Sample Code
// Courtesy of Bruce Carneal
import core.atomic : atomicOp, atomicLoad;
import std.parallelism : parallel;
import std.range : iota;
import std.stdio : writeln;
enum threadCount = 100;
enum incrementsPerThread = 10000;
enum expected = threadCount * incrementsPerThread;
void main() {
shared(ulong)* counter = new ulong;
// Forces 100 threads by limiting the number of work items per thread to '1'
foreach (i; parallel(iota(0, threadCount), 1)) {
foreach (_; 0 .. incrementsPerThread)
atomicOp!"+="(*counter, 1);
}
writeln("Expected total count: ", expected, "; Actual count: ", atomicLoad(*counter));
}
Memory Safety Features
Memory / Lifetime Management: pure functions, @safe code, optional Garbage
Collection, scoped pointers, RAII, contracts, member access protection Automatic Bounds Checking: Yes
Safe Arithmetic: No, Yes with library functions
Pointers and References: Both
References are safer Forced Initialization: Yes, but can turn off in @system
code
Pointer Arithmetic: Yes, but only in @system code
Managed Ownership: Garbage Collection, ref counting library type
Thread Safety Features
Sync Primitives: Atomics, Locks, Memory Barriers
Reentrant Safety: Yes if you use only local data and avoid shared mutable state Thread Local Storage: Yes (by default)
Immutable Objects: Yes, and const/immutability is transitive
Immutable by Default: No
Communication Primitives: Library
Performance
Translation: Compiled, matches C/C++ performance
Deterministic @ Runtime: Yes
Bare Metal Programming: Yes (includes inline assembler!)
Other Features: Excellent meta programming enabling easy refactoring for
more efficient algorithms, compile time function evaluation, bitfields, array
operations, SIMD code generation
Development Ecosystem
Available Tool Chains: Digital Mars D, Gnu D, and LDC
D Library Support: Some, C libraries are accessible via ImportC
Package Managers: DUB IDE / Editor
Support: Many, including dedicated IDEs like Dexed and D-Veldop, as well as plugins for popular editors like IntelliJ IDEA, Visual Studio Code, and more. Language Server Available: Yes - serve-d
Community: Medium
Other Considerations
Easy or hard to learn? Remarkably easy to learn, code is easy to read
Easy or hard to find developers? C and C++ programmers fit right in, Python
programmers report it's an easy transition to D
Suitable for use in regulated environments? Yes
Suitable for use in embedded environments? Yes
Job Availability by career level: at all levels
Special features: Best metaprogramming, easiest compile time function
execution, can import C code directly, excellent module system, pure
functions, lambdas, ranges, forward referencing, nested functions, static
asserts (copied by other languages!)
Lloyd Moore
C++








Brad Gibson
Rust
Rust
What is It?
Rust is a compiled, non-garbage-collected, multi-paradigm
systems programming language designed to to operate in the same spaces as both C and C++.
Rust
Who Created It?
Rust was created by a language engineer named
Graydon Hoare.
Rust
Where Was Rust Created?
Graydon worked at Mozilla when he started developing Rust as a personal project.
Rust
When was Rust Created?
Graydon started to work on Rust in 2006.
Rust 1.0 was released May 15, 2015.
Rust
Language Goals:
- Reliability
- "Rust’s rich type system and ownership model guarantee memory-safety and thread-safety — enabling you to eliminate many classes of bugs at compile-time."
- Performance
- C and C++ class performance
- Productivity
- Very good documentation
- Friendly compiler (usually), if strict
Why Was Rust Created?


Rust
How Was Rust Created?
- Rust bootstrapping α-compiler released in 2010 (OCaml).
- Rust becomes self-hosting in early 2011.
- Rust 1.0 (production, stability guarantees) was released May 15, 2015 (Rust).
Graydon cites inspiration from Ada, OCaml, CLU and Hermes.
Wikipedia also lists Alef, BETA, C#, C++, Cyclone, Elm, Erlang, Haskell, Limbo, Mesa, Napier, Newsqueak, NIL, Ruby, Sather, Scheme, Standard ML and Swift as influences.
Rust
Release Schedule
- Release Cadence: every 6 weeks
- Edition cadence: every 3 years
- Editions permit (limited) breaking language changes
with both backward and forward compatibility (!)
- Editions permit (limited) breaking language changes
Rust
Status
- Latest release: 1.88.0 (June 26, 2025)
- Safety-critical Rust (Ferrocene) is currently qualified as:
- ISO 26262 & ASIL-D (automotive)
- IEC 61508 (SIL 4) (industrial manufacturing)
- IEC 62304 (Class C) (medical development)
- GCC back-end support under development (currently LLVM)
- No ISO standards body; is not an explicit goal
- Rust Language Team uses a public request-for-comments model
Rust Example Code (Atomics)
use std::{any::Any, sync::atomic::{AtomicU64, Ordering}, thread};
type Result<T, E = Box<dyn Any + Send + 'static>> = core::result::Result<T, E>;
const THREAD_COUNT: usize = 100;
const INCREMENTS_PER_THREAD: usize = 10_000;
static COUNT: AtomicU64 = AtomicU64::new(0);
fn main() -> Result<()> {
let mut join_handles = Vec::with_capacity(THREAD_COUNT);
// Spawn all the threads
for _ in 0..THREAD_COUNT {
let join_handle = thread::spawn(|| {
for _ in 0..INCREMENTS_PER_THREAD {
// Read/Modify/Write is atomic (indivisible) and cannot race. Look Ma, no locks!
COUNT.fetch_add(1, Ordering::SeqCst); // <-- SeqCst is conservative but never wrong
}
});
// Add the newly created thread's handle to the list of already-created handles
join_handles.push(join_handle);
}
// Wait for all threads to complete
join_handles.into_iter().try_for_each(|jh| jh.join())?;
// Print the total count.
println!("Total count is {}", COUNT.load(Ordering::SeqCst));
Ok(())
}
❯ cargo run
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
Running `target/debug/inc_locked`
Total count is 1000000
Process finished with exit code 0
Learning Resources
Coming from:
* C or C++? Programming Rust, Rust for Rustaceans
* Above or Other Languages? The Book
Looking for:
- Hands On?
Rustlings, Rust by Example, 100 Exercises To Learn Rust, The Rust Cookbook - Embedded? Embassy Book, Embedded Book
- Advanced? Rust Atomics & Locks, Rust Reference, Rustonomicon
- Web Assembly? Rust and WebAssembly Book
Memory Safety Features
Memory Management
* RAII (i.e. scope-based), Manual
* Compiler-enforced without runtime via borrow-checker
* Ref-counted memory resources also available (opt-in)
Lifetime Management
* Manual
* Common cases can be elided
* Can be complex
* Compiler-enforced without runtime via borrow-checker
Memory Safety Features
Bounds-Checking
* Yes, by default (impacts performance)
* Can be manually overridden (`unsafe`)
* Compiler often automatically elide bounds checking esp. when using functional paradigms
Safe Arithmetic
Integer Arithmetic
- Defaults to C model: panic on debug, wrap (silently) in release; no UB!
- supports safe integer arithmetic (`checked`, `wrapping`, `overflowing`, `saturating`)
Floating Point: IEEE-754-2008
Memory Safety Features
Pointers and References
* Yes, all Rust's safe pointers are... safe (`Arc`, `Box`, `RefCell`, et. al.)
* References (`&`, `&mut`) cannot be null and are always initialized (language invariant)
* Additional `unsafe` pointers are available (`UnsafeCell`, `*const`, `*mut`, et. al.)
* No `unsafe` nullable reference.
Forced Initialization
* Safe (default) Rust ensures all memory, types, references and safe pointers are initialized
* `unsafe` resources may require manual initialization
* Pointer arithmetic is supported (unsafe, via `.add`, `.offset`, et. al.)
Memory Safety Features
Managed Ownership (Borrow-Checker)
* Compile-time--the benefits of GC/RC without any runtime overhead
* Via strict alias tracking and static analysis
* No additional code at runtime
* Aliasing guarantees provide additional compiler optimizations not possible otherwise
Thread Safety Features
Sync Primitives
* `Mutex`, `RwLock`, `Condvar`, guaranteed one-time initialization, Atomics, Memory Barriers (C++11 Model)
Reentrancy Safety
* Not by default; non-rentrancy-safe functions are safe from data races but may deadlock or panic (orderly termination of app).
* Careful design (manual) can yield reentrancy safe functions.
Thread Safety Features
Immutability
* Rust bindings (variables) are immutable by default.
* Immutability cannot be cast away.
Communication Primitives
* MPSC (Multiple-Producer, Single Consumer) channel, bounded and unbounded
* Other variants available as 3rd party libraries
* Streams, Websockets
* Unix pipes are not directly supported in `std`.
Performance
Determinism @ Runtime:
* Rust is suitable for hard realtime development, with careful use.
* Some types and functions are not suitable for hard-realtime use (e.g. `Vec`).
Bare Metal Programming
* Rust is suitable for bare-metal programming
* Innovative representation of hardware using typestate
* Innovative representation of hardware using `async`
Development Ecosystem
Available Toolchains
* `rustc` + LLVM
* Ferrocene (safety-qualified compiler)
* Cranelift
* `gccrs`, `rustc_codegen_gcc` (under development)
* `mrustc`
Library Support
* Good
* Some areas are thinner (ML/AI, UI, scientific, GPU), but options usually exist.
Development Ecosystem
Package Managers
* `cargo` is effectively the universal standard in Rust
IDE Editor Support
* `rust-analyzer` is a Rust Language Server Protocol (LSP) server implementation designed for use in most editors--`vim`, `emacs`, VSCode, Helix, `zed`, Sublime Text...
* Rust Rover or IntelliJ Rust for JetBrains IDE's
Community Size
* Medium to large and fast-growing
Other Considerations
Easy or Hard?
* Hard; Rust is not a small language and has some advance concepts.
Easy to Find Developers?
* In recent years, it has become reasonably easy to find Rust developers.
Other Considerations
Suitable for Use in Regulated Environments?
Yes, some:
- ISO 26262 & ASIL-D (automotive)
- IEC 61508 (SIL 4) (industrial manufacturing)
- IEC 62304 (Class C) (medical development)
- more in progress
Suitable for Use in Embedded Environments?
* Yes. Jobs appearing in everything from automotive to NewSpace; clean energy to medical devices.
Other Considerations
Job Availability By Career Level
* Junior: scarce
* Mid-level: moderately scarce
* Senior: Moderate
* Staff/Principal: Moderate
Rust Example Code (Mutex Lock)
use std::{any::Any, thread, thread::JoinHandle};
use parking_lot::Mutex;
type Result<T, E = Box<dyn Any + Send + 'static>> = core::result::Result<T, E>;
const THREAD_COUNT: usize = 100;
const INCREMENTS_PER_THREAD: usize = 10_000;
static COUNT: Mutex<u64> = Mutex::new(0); // <-- New!
fn main() -> Result<()> {
let mut join_handles = Vec::with_capacity(THREAD_COUNT);
// Spawn all the threads
for _ in 0..THREAD_COUNT {
let join_handle = thread::spawn(|| {
for _ in 0..INCREMENTS_PER_THREAD {
let mut count_guard = COUNT.lock(); // <-- returns resource *guard*, not resource!
*count_guard += 1; // <-- dereference guard to access `COUNT`. And no more `unsafe`!
} // <-- guard drops automatically (unlocks), making lock available to other threads
});
// Add the newly created thread's handle to the list of already-created handles
join_handles.push(join_handle);
}
// Wait for all threads to complete
join_handles.into_iter().try_for_each(JoinHandle::join)?;
// Print the total count.
println!("Total count is {}", *(COUNT.lock())); //<-- Get lock, deref guard, get value, release
Ok(())
}
❯ cargo run
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
Running `target/debug/inc_locked`
Total count is 1000000
Process finished with exit code 0
Rust Example
Code (Racy☠️)
use std::{any::Any, thread};
type Result<T, E = Box<dyn Any + Send + 'static>> = core::result::Result<T, E>;
const N_THREADS: usize = 100;
const INCS_PER_THREAD: usize = 10_000;
static mut COUNT: u64 = 0;
fn main() -> Result<()> {
let mut join_handles = Vec::with_capacity(N_THREADS);
// Spawn all the threads
for _ in 0..N_THREADS {
let join_handle = thread::spawn(|| {
for _ in 0..INCS_PER_THREAD {
COUNT += 1;
}
});
// Add newly created thread's handle to list of already-created handles
join_handles.push(join_handle);
}
// Wait for all threads to complete
join_handles.into_iter().try_for_each(|jh| jh.join())?;
// Print the total count. It will be 1_000_000, right? Right?? ;)
println!("Total count is {}", unsafe { COUNT });
Ok(())
}
error[E0133]: use of mutable static is unsafe and requires unsafe block
--> src/main.rs:16:9
|
16 | COUNT += 1;
| ^^^^^ use of mutable static
|
= note: mutable statics can be mutated by multiple threads: aliasing violations or
data races will cause undefined behavior
Rust Example
Code (Racy☠️)
use std::{any::Any, thread};
type Result<T, E = Box<dyn Any + Send + 'static>> = core::result::Result<T, E>;
const THREAD_COUNT: usize = 100;
const INCREMENTS_PER_THREAD: usize = 10_000;
static mut COUNT: u64 = 0;
fn main() -> Result<()> {
let mut join_handles = Vec::with_capacity(THREAD_COUNT);
// Spawn all the threads
for _ in 0..THREAD_COUNT {
let join_handle = thread::spawn(|| {
for _ in 0..INCREMENTS_PER_THREAD {
unsafe { COUNT += 1; }
}
});
// Add newly created thread's handle to list of already-created handles
join_handles.push(join_handle);
}
// Wait for all threads to complete
join_handles.into_iter().try_for_each(|jh| jh.join())?;
// Print the total count. It will be 1_000_000, right? Right?? ;)
println!("Total count is {}", unsafe { COUNT });
Ok(())
}
❯ cargo run
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.10s
Running `target/debug/inc_racy`
Total count is 192008
❯ cargo run
Total count is 189345
❯ cargo run
Total count is 198313
❯ cargo run --release # <-- compile in release mode
Finished `release` profile [optimized] target(s) in 0.00s
Running `target/release/inc_racy`
Total count is 1000000 # <-- !!
Rust
Why Was Rust Created?
"A lot of obvious good ideas, known and loved in other languages, haven't made it into widely-used systems languages, or are deployed in languages that have very poor (unsafe, concurrency-hostile) memory models. There were a lot of good competitors in the late 70s and early 80s in that space, and... circumstances have changed: the internet is highly concurrent and highly security-conscious, so the design-tradeoffs that always favor C and C++ (for example) have been shifting."
Thank you.
SRUG 2025.07: Language Panel
By u007d
SRUG 2025.07: Language Panel
- 103