在 c 中转换一个 volatile 变量后,该变量是否仍然是 volatile?
After casting a volatile variable in c, is the variable still volatile?
假设我有一个静态全局变量 a,它在 init() 期间的函数调用中被强制转换为一个 int。在init()之后,a在函数my_function_2中使用时是否仍然易变?
static volatile int a;
init(void)
{
my_function_1((int)a);
}
my_function_2(void)
{
/* After init(), is a still volatile? */
}
a 是否需要在 my_function_2() 中重新限定为 volatile?我正在使用 c99。
volatile的意思基本上就是可以被外部修改。这永远不会改变。如果您已将变量声明为 volatile,那么它就是 volatile。
变量 a
在其整个生命周期内都是易变的。如果你将它转换为一些不同的类型并将它分配给一个新变量,那么这个新变量将不会是 volatile
除非你指定它。
volatile
意味着编译器不依赖于先前已知的值并且不应应用适当的优化,因此如果您放弃它并仍然引用它,那么它就是未定义的行为。
这里不需要声明b为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);
}
另一个例子:
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);
}
通过非限定类型引用值是未定义的行为。如果您“丢弃”volatile
,则不允许您通过非易失性限定类型访问该内存位置。
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
但是您仍然可以复制它:
static volatile int a;
int b = a; // ok, lvalue conversion, drops qualifiers during copy
*(int*)&a = ... // undefined behavior
一个cast只能转换一个值;它不能影响 object (变量的内存)。并且值没有限定符,例如 volatile
.
当在表达式中使用 object 的值时,根据 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;…
因此,在 (int)a
中,a
在转换发生之前从 volatile int
左值转换为 int
值 .强制转换无效;它将 int
转换为 int
。另请注意,该值是强制转换的——您的标题询问“强制转换可变变量”,但无法强制转换变量,因为它会在强制转换之前自动转换为它的值。
所以演员对 a
没有影响。 object a
仍然不稳定。它的值作为没有 volatile
限定符的值传递给 my_function_1
。
假设我有一个静态全局变量 a,它在 init() 期间的函数调用中被强制转换为一个 int。在init()之后,a在函数my_function_2中使用时是否仍然易变?
static volatile int a;
init(void)
{
my_function_1((int)a);
}
my_function_2(void)
{
/* After init(), is a still volatile? */
}
a 是否需要在 my_function_2() 中重新限定为 volatile?我正在使用 c99。
volatile的意思基本上就是可以被外部修改。这永远不会改变。如果您已将变量声明为 volatile,那么它就是 volatile。
变量 a
在其整个生命周期内都是易变的。如果你将它转换为一些不同的类型并将它分配给一个新变量,那么这个新变量将不会是 volatile
除非你指定它。
volatile
意味着编译器不依赖于先前已知的值并且不应应用适当的优化,因此如果您放弃它并仍然引用它,那么它就是未定义的行为。
这里不需要声明b为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);
}
另一个例子:
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);
}
通过非限定类型引用值是未定义的行为。如果您“丢弃”volatile
,则不允许您通过非易失性限定类型访问该内存位置。
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
但是您仍然可以复制它:
static volatile int a;
int b = a; // ok, lvalue conversion, drops qualifiers during copy
*(int*)&a = ... // undefined behavior
一个cast只能转换一个值;它不能影响 object (变量的内存)。并且值没有限定符,例如 volatile
.
当在表达式中使用 object 的值时,根据 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;…
因此,在 (int)a
中,a
在转换发生之前从 volatile int
左值转换为 int
值 .强制转换无效;它将 int
转换为 int
。另请注意,该值是强制转换的——您的标题询问“强制转换可变变量”,但无法强制转换变量,因为它会在强制转换之前自动转换为它的值。
所以演员对 a
没有影响。 object a
仍然不稳定。它的值作为没有 volatile
限定符的值传递给 my_function_1
。