You are right, the default optimization removes it.
Removes what ?
This is how "Chip_SPI_ReceiveFrame()" is defined :
STATIC INLINE uint16_t Chip_SPI_ReceiveFrame(LPC_SPI_T *pSPI)
{
return SPI_DR_DATA(pSPI->DR);
}
I suppose :
The volatile keyword is used to force a compiler to call the function "Chip_SPI_ReceiveFrame()". If the variable tmp was defined without volatile keyword i.e. just "uint32_t tmp", calling of the "Chip_SPI_ReceiveFrame()" would not be guaranteed. In this case a compiler might think: "hm, return value from "Chip_SPI_ReceiveFrame()" is stored in the non-volatile "tmp" variable on the stack and "tmp" is not used till the end of the "Chip_SPI_Int_FlushData()" so i will not call(inline) it and save time/memory."
But the volatile keyword does not give a compiler any chance to be ambiguous about calling "Chip_SPI_ReceiveFrame()" - keyword volatile guarantees that calling "Chip_SPI_ReceiveFrame()" will not be optimized away.