Interrupts and variables as arguments

So this question came up on me and I don't know the answer at all. If I have a volatile variable at global scope but I use it as an argument to a function anyway and the variable updates while I am in the function what will happen? Does it make a difference if I call by reference?

This isn't really related to any code, it's just something I'm trying to wrap my head around trying to understand how some of these things are related.

Say I have:

 volatile int a = 0;

void myISR()
{
     a++
}

void callByValue(int x)
{
     Serial.print(x);
     delay(1000);  // lets say the interrupt fires during this
     Serial.print(x);
}

void callByReference(int &x)
{
     Serial.print(x);
     delay(1000);  // lets say the interrupt fires during this
     Serial.print(x);
}

void callByPointer(int *x)
{
     Serial.print(*x);
     delay(1000);  // lets say the interrupt fires during this
     Serial.print(*x);
}


void setup()
{
     attachInterupt(0,myISR,RISING);
}

void loop()
{
     
     callByValue(a);
     callByReference(a);
     callByPointer(&a);
}

My gut tells me that calling the first function, I'll always get the same thing for both prints since it is call by value it will get called with the value of a at the time of the call. But the second case confuses me. I think that the two prints will give different values since the variable being referenced is changing but I'm not sure that's how it works.

I'm sure calling the last one by the pointer will give me two different things since that pointer is being dereferenced each time. I guess my question is does the call by reference function work the same way?

Leave the volatile modifier on, and you get the effects of 'volatile'

void callByReference( volatile int &x );
void callByPointer( volatile int *x );

Also, make any access to that variable atomic by wrapping the access in interrupts()/noInterrupts() calls so the interrupt cannot change things half way through your statement.

If it’s an 8-bit variable a standard read or write is atomic anyway so,

volatile byte var;

x = var;

is OK but

var++;

is not atomic and needs to be protected.

As you have an int (two bytes on most Arduinos) you have to protect all access to it.


Rob