I understand that the declaration
int *volatile ptr;
means that the pointer itself is volatile
int a=10;
int *volatile ptr=&a;
Now both ptr
and a
are being updated. Will it cause any potential problems like old value of a
being returned when accessing ptr
?
To clarify the use case of volatile pointer in my scenario:
My doubt is since what the pointer is pointing to is not volatile is there a chance that compiler has optimized for index x and on deferencing pointer at index x it will point to variable a instead of variable b
int* volatile
only means that the pointer itself is volatile
. The pointed-at data is not volatile-qualified, meaning that the following scenario may cause optimizer bugs:
int a=10;
int* volatile ptr=&a;
int main()
{
for(;;)
{
printf("%d\n", *ptr);
}
}
void some_ISR (void)
{
a = something;
}
The compiler is careful not to assume that ptr
does not point at the same address every lap in the loop, but apart from that it is free to assume: "aha, after reading ptr
it is still pointing at a
I see. It has not been updated and I know it is 10". In theory the compiler is free to generate machine code such as this pseudo:
val = *ptr
forever
{
ptr = (update it by reading from memory)
if ptr != previous
val =*ptr
print val
previous = ptr
}
Such optimizations may make sense if the compiler can keep the previous value stashed away in a CPU register etc. Suppose it can get rid of a lot of the printf overhead this way, that would be a major optimization.
So, no this does not give you protection against incorrect optimizations. To achieve that, use volatile int*
instead. Or if the pointers themselves may also change, volatile int* volatile
.
To communicate from interrupt context to task context I am passing addresses to circular queue (which is array of pointers) which will be accessed from task context.
That only makes sense if the pointer itself is changed to point elsewhere by the interrupt. Again, it doesn't mean that the pointed-at data will be updated. But as you write "The pointers in this queue are declared volatile.", you are good, assuming this means that the pointers are volatile* type
and not type*volatile
.
Unrelated to this whole issue, you also need a protection against non-atomic access of shared variables. volatile
does not give that.