cventu cventu - 2 months ago 5x
C Question

Casting volatile variable in c

I think I have a tricky question, but I'm sure you will be able to help me.
Let's say I have a function like this:

char my_function (int example);

I use this function in multiple cases, sometimes the argument it receives is a volatile variable and sometimes a non-volatile variable.
That cause some warnings when I compile my code that can be easily removed by using casts, but I want to understand which is the safer scenario and why.

Scenario 1:

char my_function (int example);

int a;
volatile int b;

my_function (a); // Everything is fine.
my_function ((int)b); // Avoided the warning, by casting the variable and saying it's no longer volatile.

Scenario 2:

char my_function (volatile int example);

int a;
volatile int b;

my_function(b); // Everything is fine.
my_function((volatile int)a); // Avoided the warning, by casting 'a' saying that now it's volatile.

I understand how volatile modifier works, I mostly use it because I program micro-controllers and I need to ensure that some of my variables are never optimized out when they are hardware modified.
I am a bit confused about casting the volatile modifier and that is why I want to understand which is the safer scenario apart from just removing the warning.


It really depends on what my_function does with its argument.

Remember that volatile prevents certain optimizations - predominantly it forces the variable to be re-read every time it is referenced. Thus this code

volatile int a;
int b;
// ...
b = a + 1;
b = a + 2;

will read a for each statement and, as a may have changed values between them, give the correct result.

When you pass a volatile into a function as a parameter, you only get one read of the variable. This may then be used multiple times within the function (effectively losing the volatile nature).

Remember that C is pass-by-value. When you invoke the function as

my_function((int)b); // b is declared volatile

The compiler generates code to read b once in the calling code, and push the value it read onto the stack (usually), then invoke my_function. This copy is then referenced within my_function as example, and no matter how often you reference example you will always get the same value (even if the original b variable has since changed many times).

That might be exactly what you want - take a snapshot of the variable and do several computations on its value.

If it's not what you want, you need to consider passing in a pointer with the appropriate volatile qualifications.

char my_function( volatile int *example);

And call it thus:


Then reference *example inside my_function.