Reading the interrupt state register using the pointer passed to (volatile uint32_t *) tells the compiler that reading this expression (a variable at the specified address) creates side effects, so you should always evaluate this expression.
Since your tmp variable is unstable, the compiler can optimize the storage time of your register value in the variable.
I think that chapter 5.1.2.3 of standard C (see here) is quite relevant.
Additionally, chapter 6.7.3 explains:
An object that has a mutable type can be modified in ways that are unknown to the implementation or have other unknown side effects. Therefore, any expression that refers to such an object is evaluated strictly in accordance with the rules of an abstract machine, as described in 5.1.2.3. In addition, at each point in the sequence, the last value stored in the object agrees with what is prescribed by the abstract machine, with the exception of cases of unknown factors mentioned earlier. 116) What constitutes access to an object that is of an unstable type is determined by the implementation.
In fact, you can omit tmp and just write:
*(volatile uint32_t *)INTERRUPT_STATUS_REG_ADDRESS;
It will just read the uint32_t register located in INTERRUPT_STATUS_REG_ADDRESS;
source share