Probably someone wrote bad code once and got away with it (probably ran his demo for the 30s youTube video
) and then many others copied without thinking about it....
The reality is that indeed you need to inform the compiler that some optimisations are not welcome (that's the volatile keyword) and then there is also the concept of atomicity or critical sections. Those are crucial concepts for ensuring proper handling of shared variables and data consistency.
➜ The volatile keyword tells the compiler that a variable's value can change at any time, even outside the current program's flow, such as due to an interrupt. This prevents the compiler from optimising away repeated reads or writes to that variable, ensuring that the most up-to-date value is always accessed.
in @arduinoer_cc's code he was using errorIsr as a shared variable and the loop was accessing it both in reading and writing mode.
In this example, the compiler could decide to embed the loop() function within main() since it's pretty trivial
int main(void) {
init();
initVariant();
setup();
for (;;) {
if (++loopIng >= 32000000) {
Serial.println("Running"); //Run?
loopIng = 0;
}
if (errorIsr == 1) {
Serial.println("error");
errorIsr = 0;
}
}
return 0;
}
and then further optimise since nothing is modifying errorIsr and it's probably 0 to start with and get totally rid of it and compile
int main(void) {
init();
initVariant();
setup();
for (;;) {
if (++loopIng >= 32000000) {
Serial.println("Running"); //Run?
loopIng = 0;
}
return 0;
}
using volatile is what tells the compiler that errorIsr can be modified
➜ Atomic operations or critical sections deal with ensuring that shared resources are accessed safely when they can be modified by both the main program and interrupt service routines. An atomic operation is one that completes entirely without being interrupted, guaranteeing consistent state changes. A critical section is a portion of code that ensures mutual exclusion, meaning only one context (either the interrupt or the main program) can execute it at a time. (In embedded C++, critical sections are often implemented using techniques like disabling interrupts temporarily during sensitive operations.)
in the code @arduinoer_cc wrote, there is not really dire consequences if we don't implement a critical section and that the value of errorIsr is modified between the if and when it's reset to 0 (even if this variable is not a bool or byte given it's only 0 and 1).