the data-race-free (DRF) guarantee
/ DRF -> dee-ar-EFF /
The data-race-free guarantee is the deal the memory model offers you, and it is generous: 'write a program with no data races, and I will let you reason about it as if it ran under simple sequential consistency — one global interleaving, no weird reorderings to think about.' All the frightening complexity of weak orderings only matters if you go out of your way to use relaxed atomics; for ordinary, properly-synchronized code, DRF gives you back your intuition.
First, the definitions. Two memory accesses CONFLICT if they touch the same location and at least one is a write. A DATA RACE is two conflicting accesses from different threads that are not ordered by happens-before and at least one is a non-atomic, ordinary access. A program is data-race-free if no execution can ever exhibit such a pair. You achieve that by guarding every shared mutable location — with a mutex, or by making it atomic, or by establishing a release/acquire happens-before edge between every conflicting pair.
Now the hard, non-negotiable rule: in C, C++, and safe-vs-unsafe Rust alike, a data race is UNDEFINED BEHAVIOR. This is the part people underestimate. Undefined behavior does NOT mean 'you get a garbled value' or 'it is unpredictable but bounded'. It means the standard imposes no requirements whatsoever, so the optimizer is entitled to ASSUME your program has no data races and may delete code, fuse loads, or produce output that looks impossible — possibly with no crash at all. 'It worked in my testing' proves nothing about a racy program. (Safe Rust is special: its borrow checker statically PREVENTS data races at compile time, which is its headline guarantee — but unsafe blocks and FFI can still create them.)
int flag = 0; /* plain int, NOT atomic */ T1: flag = 1; /* write */ T2: while (!flag) {} /* read */ <- conflicting, unordered, non-atomic = DATA RACE = UB The compiler may legally hoist !flag out of the loop and spin forever, or optimize the loop away.
A non-atomic flag spun on by two threads is undefined behavior — making flag _Atomic fixes it.
A data race is UNDEFINED BEHAVIOR, not merely a wrong value: the compiler may assume it cannot happen and miscompile the whole region, so a race that 'never showed up in testing' can detonate after any optimization or platform change.