Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C: Volatile Arrays in C

The volatile keyword is used in C to prevent the compiler performing certain optimizations, amongst other subtle changes, on a variable.

For example;

volatile int my_int = 0;

creates an integer. In some situations it may prevent the following optimization:

while(my_int == 0); // Loop until my_int != 0

Optimize to:

while(1); // Loop infinity.

This is useful for situations including those frequently encountered in embedded systems, such as a situation where modification to a variable may be made by an interrupt function call. There are many other examples of where this technique is useful. my_int may be a flag which is modified by such a function. (This is just a toy model.)

However, consider the case where the data modified by the function is an array. The data may be pointed to by a pointer.

unsigned char* my_data = new unsigned char[256];

In this case, considering that my_data is a global variable in this specific situation of this question[1], is the volatile keyword redundant, or is it still required?

[1] It may not matter.

If the answer is that the volatile keyword is required, what it the correct syntax for use?

For example, volatile unsigned char* my_data, I assume declares that the pointer itself is volatile, and not the data it points to.

Finally, is there a difference between the use in C and C++?

like image 442
FreelanceConsultant Avatar asked Aug 15 '14 18:08

FreelanceConsultant


People also ask

What is volatile array?

Making an array volatile i.e. can access individual elements of these arrays represented by these classes as volatile variables. These classes provides get() and set() variables to retrieve or, assign values to each elements individually.

What is the volatile in C?

The volatile qualifier is applied to a variable when we declare it. It is used to tell the compiler, that the value may change at any time. These are some properties of volatile. The volatile keyword cannot remove the memory assignment. It cannot cache the variables in register.

Does C have volatile?

Volatile is used in C programming when we need to go and read the value stored by the pointer at the address pointed by the pointer. If you need to change anything in your code that is out of compiler reach you can use this volatile keyword before the variable for which you want to change the value.

Can array be declared volatile?

Yes, you can make the array volatile but that will only cover change to the reference variable pointing to an array, it will not cover changes in individual array elements.


3 Answers

Yes, volatile is required, and the right declaration is:

volatile unsigned char *my_data;

This declares my_data to be a pointer to volatile unsigned char.

To make the pointer itself volatile, you'd need this instead:

unsigned char *volatile my_data;

And of course, both the pointer and the pointed-to data may be volatile:

volatile unsigned char *volatile my_data;

There's no difference between C and C++.

like image 150
Filipe Gonçalves Avatar answered Oct 08 '22 14:10

Filipe Gonçalves


Filipe Gonçalves have already provided an answer, but I would like to elaborate a bit.

Basically, the volatile keyword is required whenever you would like your program to really consider the variable value, without trying to be smart. It does not matter what kind of variable you have, it's just that if compiler can't see any changes to a variable between the assignment and the call, it will probably optimize it (depending on your settings of course).

From compiler's POV, the sequence of events is "assign 0 to Var"->"do unrelated stuff, but surely not touching Var"->"check Var value" It does not matter where and how variable Var got declared, and the code will be optimized unless volatile keyword is used.

like image 2
ZenJ Avatar answered Oct 08 '22 15:10

ZenJ


C declarations are to be read form right to left with qualifiers to the left.

So volatile char * x means 'x' is a pointer to a volatile char. while char volatile * x means that 'x' is a volatile pointer to a char

The difference in pactice is that when accessing x[0], in the first case, the value at x[n] needs to be read on each appearance in the source code (e.g. twice in a = x[n]*x[n])

In the second case, x iteself needs to be read each time and then the address of x[n] needs to be calculated again and then x[n] is to be read.

For this reason, volatile char volatile *x is redundant.

However, declaring an array or its elements as volatile will prevent the compiler from buffering them across multiple reads. It does not ensure that a function that reads a volatile array won't read first half of the array while it contains old values and (after an external change) the second half while it contains updated values, leading to an inconsistent result. Using volatile on arrays or structs (or sets of individual variables) is only advisable when the individual elements are independent of each other. If changing one of them affects the others (or their use/meaning), then volatile won't help at all and a mutex should be used for the whole access (preventing the array content to be changed during processing).

like image 1
Peter Painter Avatar answered Oct 08 '22 14:10

Peter Painter