在 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