Calls to these functions that allocate or deallocate a particular unit of storage shall occur in a single total order, and each such deallocation call shall happen before the next allocation (if any) in this order.
From what it seems to me, it only establishes a happens-before relationship between allocations and deallocations (to prevent concurrency issues arising from incorrect compiler optimisations, possibly). It definitely does not establish a relationship between a
and b
where a
and b
are different allocated regions.
Remember that compilers follow the specification, not human logic. The specification aids the compiler programmers remember all the details that need to be taken care of (if it follows specification, it's correct). This is why the specification contains details that one would consider obvious. One of the details is that the deallocation/allocation constitutes a memory barrier.
Compare
reads -> deallocation -> allocation -> writes
with
reads -> deallocation
allocation -> writes
Without a happens-before relationship, two threads may use the same memory region (unit of storage) concurrently, as observed by the memory region. With a happens-before relationship, all access from the deallocating thread must be flushed before the allocating thread gets to use it.