Hardware interrupts and signals are asynchronous to the execution of a program, be it written in C, C++ or assembly language. As such, an interrupt or signal can occur within the sequence of instructions to implement a particular C statement or even expression.
For example, consider the following simple statement in the “regular” part of a program (not in an ISR or signal handler):
On a 32-bit platform, this C statement cannot be implemented using a single instruction.
Now, consider this statement that is in an ISR or signal handler:
In this case, it is possible for variable x to end up with some hybrid values, such as 0x000000009abcdef0 or 0x1234567800000000.
Why?
The regular part of the program can execute the first instruction of the assignment statement and have half of the value copied. Then the interrupt or signal occur. The ISR or signal handler then executes its own assignment statement to x. When the ISR or signal handler returns, the “regular” part of the program continues the interrupted sequence of instructions and copies the other half of the variable.
The root of the problem is that variable x cannot be updated using an atomic (uninterruptable by interrupts or signals) operation.