1. Yep, this is an abstraction HW works hard to preserve.
2.The specific scenario I had in mind was: write value X to address A from core 1, write value Y to A from core 2, read value from address A from core 1 (still X in core 1's cache), core 1 cache gets invalidated, read value from address A from core 1 again (now it fetches Y from memory).
See [1] for reference on how it applies to C specifically, especially "Absent any constraints on a multi-core system, … one thread can observe the values change in an order different from the order another thread wrote them".