I think this example is a little too misleading. This makes it sound like *all* loop variables need to be volatile, but that's not true.

Volatile memory accesses are normally required when memory can change where the compiler has no way of knowing it can change. For example, if `i` was a shared variable the compiler may assume that you were the only thread (and hence no one else could change it). Another case is memory-mapped I/O where the hardware may change the value each time you read it.