I presume that the following will give me 10 volatile ints
volatile int foo[10];
However, I don't think the following will do the same thing.
volatile int* foo;
foo = malloc(sizeof(int)*10);
Please correct me if I am wrong about this and how I can have a volatile array of items using malloc.
Thanks.
is the way to go. The volatile type qualifier works just like the const type qualifier. If you wanted a pointer to a constant array of integer you would write:
whereas
is a constant pointer to an integer that can itself be changed. volatile works the same way.
Thanks very much to wallyk, I was able to devise some code use his method to generate some assembly to prove to myself the difference between the different pointer methods.
using the code: and compiling with -03
when p is simply declared as pointer, we get stuck in a loop that is impossible to get out of. Note that if this were a multithreaded program and a different thread wrote p[2] = 0, then the program would break out of the while loop and terminate normally.
notice that the only instruction for L6 is to goto L6.
==
when p is volatile pointer
here, the pointer p gets reloaded each loop iteration and as a consequence the array item also gets reloaded. However, this would not be correct if we wanted an array of volatile integers as this would be possible:
and would result in the loop that would be impossible to terminate in a multithreaded program.
==
finally, this is the correct solution as tony nicely explained.
In this case the the address of p[2] is kept in register value and not loaded from memory, but the value of p[2] is reloaded from memory on every loop cycle.
also note that
will generate a compile error.
I think the second declares the pointer to be volatile, not what it points to. To get that, I think it should be
This syntax is acceptable to
gcc
, but I'm having trouble convincing myself that it does anything different.I found a difference with
gcc -O3
(full optimization). For this (silly) test code:With
volatile
, and omitting (x86) instructions which don't change:Without volatile, it skips reloading
p
:After many more science experiments trying to find a difference, I conclude there is no difference.
volatile
turns off all optimizations related to the variable which would reuse a subsequently set value. At least with x86 gcc (GCC) 4.1.2 20070925 (Red Hat 4.1.2-33). :-)read from right to left "foo is a pointer to a volatile int"
so whatever int you access through foo, the int will be volatile.
P.S.
==
Meaning foo is volatile. The second case is really just a leftover of the general right-to-left rule. The lesson to be learned is get in the habit of using
instead of the more common
If you want more complicated things like "pointer to function returning pointer to int" to make any sense.
P.S., and this is a biggy (and the main reason I'm adding an answer):
I note that you included "multithreading" as a tag. Do you realize that volatile does little/nothing of good with respect to multithreading?
Yes, that will work. There is nothing different about the actual memory that is
volatile
. It is just a way to tell the compiler how to interact with that memory.