Consider the following example:
int i { 0 };
void incInt() {
++i;
}
int readInt() {
return i;
}
setup() {
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(D1), incInt, CHANGE);
}
loop() {
noInterrupts();
int currI = readInt();
interrupts();
Serial.println(currI);
}
By wrapping the call to readInt() with noInterrupts() and interrupts() it is ensured that i cannot be changed externally during the execution of readInt(). i also cannot be changed externally during the execution of incInt(), as long as it is only called as ISR (interrupt service routine). Do I still need to declare i as volatile?
Does the situation change if i is accessed directly in the main loop:
loop() {
noInterrupts();
int currI = i;
interrupts();
Serial.println(currI);
}
In other words: What is the context in which the compiler expects a variable to not be changed externally if it is not declared volatile?