Reputation: 155
Let's say that I have a static global variable a, that is cast to an int in a function call during init(). After init(), is a still volatile when used in the function my_function_2?
static volatile int a;
init(void)
{
my_function_1((int)a);
}
my_function_2(void)
{
/* After init(), is a still volatile? */
}
Does a need to be re-qualified as volatile in my_function_2()? I'm using c99.
Upvotes: 0
Views: 533
Reputation: 222828
A cast can only convert a value; it cannot affect an object (the memory of a variable). And values do not have qualifiers such as volatile
.
When an object’s value is used in an expression, qualifiers are removed, per C 2018 6.3.2.1 2:
Except when it is the operand of the
sizeof
operator, the unary&
operator, the++
operator, the--
operator, or the left operand of the.
operator or an assignment operator, an lvalue that does not have array type is converted to the value stored in the designated object (and is no longer an lvalue); this is called lvalue conversion. If the lvalue has qualified type, the value has the unqualified version of the type of the lvalue;…
So, in (int)a
, the a
is converted from a volatile int
lvalue to an int
value before the cast occurs. The cast has no effect; it converts an int
to an int
. Also note that the value is cast—your title asks about “casting a volatile variable,” but it is impossible to cast a variable, because it is automatically converted to its value before the cast.
So the cast has no effect on a
. The object a
remains volatile. Its value is passed to my_function_1
as a value without the volatile
qualifier.
Upvotes: 1
Reputation: 22094
The variable a
will be volatile for it's entire lifetime. If you cast it to some different type and assign it to a new variable, then this new variable will not be volatile
unless you specify it so.
volatile
means that the compiler doesn't rely on a previously known value and should not apply appropriate optimizations, so if you cast that away and still reference it , than it is undefined behavior.
Here you don't need to declare b as volatile
volatile int a;
void func(int b)
{
// This doesn't need to be volatile as it will never be changed from the outside, since it was passed by value.
printf("%d\n", b);
}
init(void)
{
// Access a and pass the value to func
// This is fine, because volatile applies only to access of 'a'.
func(a);
}
Another example:
void func(volatile int *p)
{
// 'p' needs to be volatile as it will reference 'a' which is volatile
printf("%d\n", *p);
}
init(void)
{
func(&a);
}
Upvotes: 2
Reputation: 213872
It's undefined behavior to refer to the value through a non-qualified type. If you "cast away" volatile
you aren't allowed to access that memory location through a non-volatile qualified type.
C17 6.7.3/6:
If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined
You can however still do a copy of it:
static volatile int a;
int b = a; // ok, lvalue conversion, drops qualifiers during copy
*(int*)&a = ... // undefined behavior
Upvotes: 1
Reputation: 31389
What volatile means is basically that it can be modified externally. This can never change. If you have declared a variable as volatile, then it is volatile.
Upvotes: 1