22

我正在查看以下代码:

inline void* interlocked_read_acquire(void* volatile* x);

我想知道为什么不只是volatile void*作为一个论点。一般来说, a 的语义或定义是volatile*什么?我还假设您可以将volatile*限定符与除 void 之外的任何其他类型一起使用。那是对的吗?

4

4 回答 4

21

使用cdecl顺时针螺旋规则来破译 C 风格的声明:

void* volatile* x
  • 将x 声明为指向 void 的 volatile 指针

这不同于:

volatile void* x
  • 将x 声明为指向 volatile void 的指针
于 2014-11-28T04:00:31.763 回答
10

想知道为什么 [ void* volatile*and] 不只是volatile void*...?

它们是不同的东西。

  • void* volatile*是一个指向 volatile ( void*) 的指针(因此可以在不强制转换的情况下取消引用和访问volatile void*,但只会给你一些内存中尚未指定的东西的地址)

  • volatile void*是指向 volatile 的指针void(因此您必须强制转换为 sayvolatile int*volatile My_Class*取消引用之前的类型)

于 2014-11-28T04:01:17.183 回答
7

void * ptr1;表示这ptr1是一个类型为 的变量void *。这种类型表示一个“通用指针”——它指向某个内存位置,但不包含该位置的类型信息。

void * volatile ptr2;表示该变量ptr2也是一个泛型指针,但ptr2也是volatile. 该关键字volatile称为cv 限定符,它的语法规则与const.

volatile 变量的含义是当其他一些代码说ptr2时,编译器无法优化它;它必须读取或写入存储的内存位置ptr2;它必须考虑到某些外部进程也在读取或写入该位置的可能性。

最后,void * volatile *x是可以指向的东西ptr2。例如我们可以有void * volatile * x = &ptr2;. *x = NULL;例如,如果我们接着写, then*x的类型void * volatile与我们刚刚看到的 for 具有相同的含义ptr2

如果您省略了限定符,编译器会抱怨,例如void * *y = &ptr2;. 这是因为表达式*y将具有类型void *(非易失性),因此编译器可能会围绕它执行优化,但这是不正确的行为,因为ptr2不允许这些优化。(您可能会认识到“volatile-correctness”与 const-correctness 是同一类东西)。

于 2014-11-28T05:25:41.550 回答
-1

volatile 是一个附加属性,您可以先将其删除以读取

void* volatile* x

至:

void* *x

这很熟悉。例如,一个 malloc-ed 内存指针数组。你不会混淆

volatile void*

这减少到

void* x.
于 2018-03-04T23:56:10.670 回答