Nope, you don't understand how compilers optimize... Declare all the variables that aren't const
as volatile and it is guaranteed to work whatever the optimization level or version of the compiler.
I assume your comment was aimed at me.
Sure your above statement about always using volatile if not const is correct. However, that is not what you said in your previous statement:
Just always declare variables volatile if you read or write them in an ISR. Otherwise the compiler can
optimize them away in various (hard to predict) circumstances.
Your previous statement is simply factually incorrect for the situation when only the ISR is using/accessing the global variable.
This new statement is pushing ALWAYS using volatile which an excessive and unneeded use of volatile that will disable certain types of optimizations for situations when it is not needed.
There is never an issue of accessing a stale version of a global variable if there is only a single context since there is no other context that is potentially modifying the variable out of view of the compiler for the localized code in the module being compiled.
That context can be foreground or ISR doesn't matter.
Also, any/all local optimizations related to variable caching into registers is guaranteed to be flushed back to the variable memory across function calls.
When volatile is not used, the compiler can never optimize away the memory updates of the global variable since the variable is global in scope and the compiler must ensure that all other code outside of this scope has access to the updated variable once the local scope completes/finishes/exits/calls a sub function.
And this is the reason a global variable can be modified and the modified/updated variable can be seen by a sub function that is called.
While there are some cases where volatile can and must be used to force immediate memory access (like to h/w registers to ensure certain sequencing/ordering) it is not necessary to use volatile to cause an ISR to update global variables that only the ISR uses.
The global variable is guaranteed to be updated back to memory before the ISR exits so the updated value will be seen when the ISR runs again.
There were some cases about 8-9 years ago when this wasn't the case, but this was actually a compiler issue with the pre/post pre-amble code being used by the compiler for ISR functions.
The ISR was incorrectly handling registers and pre-maturely returning, it affect globals as well as caused some register corruption.
Once that bug was fixed, the issue went away.
I actually smashed into this the 3rd day I starting using avr-gcc.