Implementation detail answer:
While the language standard classifies this as undefined behavior, you can actually feel quite safe as long as you are really writing the same data.
Why? The hardware sequentializes accesses to the same memory cell. The only thing that can go wrong is when several memory cells are written at the same time, because then you have no guarantee by the hardware that the accesses to several cells are sequentialized in the same way. For example, if one process writes 0x0000000000000000
, and another writes 0xffffffffffffffff
, your hardware may decide to sequentialize the accesses to the different bytes differently, resulting in something like 0x00000000ffffffff
.
However, if the data written by both processes is the same, then there is no noticeable difference between the two possible serializations, the result is deterministic.
Modern hardware does not handle memory accesses in a byte by byte fashion, instead, CPUs communicate with the main memory in terms of cache lines, and cores can usually communicate with their caches in terms of 8-byte words. As such, setting a properly aligned pointer is an atomic operation which can be relied on to implement lockfree algorithms. This has been exploited in the Linux kernel before more powerful atomic operations became available. C++ formalizes this in the form of atomic<>
types, adding support for the more high level hardware features like write after read, atomic increments and such.
But, of course, if you rely on your hardware details, you really should know what you are doing before you do it. Otherwise stick to language features like the atomic<>
types to ensure proper operations and avoid UB.
@Downvoters:
The question is not tagged [language-lawyer], and the answer explicitly states "Implementation detail answer". It was intentional to explain what the UB in the program will look like in real life. This answer has been written to complement the accepted answer (which has my upvote) with a different perspective on the question.