C is definitely impure. There is a large set usage cases where the memory layouts are important. Where the orders of operation and memory accesses are important.
What I worry about is when the optimizer is allowed to make assumptions about undefined behavior, that may be actually important on certain targets. Consider referencing a null pointer.
Winows7, Linux, in user land if you do that and you'll get a seg fault. And if the default handler runs your program dies.
The ARM cortex processor I've been slopping code for, reading a null pointer returns the initial stack pointer. Writing generates a bus fault. Since I actually trap that, and error message gets written into non-initialize memory and then the processor gets forcibly reset.
On an AVR reading a null pointer gives you the programs entry point. Writing to that location typically does nothing. Though you can write to it if running out of a special 'boot sector' and you've done some magic incantations.
So that's the problem I have with the idea that 'undefined means the optimizer can make hash of your program' instead of trusting the back end of the compiler will do something target appropriate.
*(unsigned long*)0xEF010014 = 0x1C;
presumes memory mapped I/O, a 32-bit hardware register at 0xEF010014, and what 0x1C will mean to that register. It also presumes that the compiler will generate a 32-bit access for an unsigned long.Going back to Gibbon1's code sample, you have to know what your compiler is going to do at what optimization level. You either have to declare spi.S to be volatile, or you have to compile at -O0, or some such. And you may well need to review the generated assembly code a few times in order to really understand what your compiler is doing with your code.
If you're writing the Linux kernel and you want to be portable across hardware architectures, it gets harder. You can't just be processor- or hardware-specific. You probably need the volatile keyword. I don't know what the kernel compiles in terms of optimizations, but I bet it's not aggressively optimized.
(I believe I follow the intended conversational import; I certainly follow the code.)