不清楚的分配原因丢弃了挥发性限定词

时间:2019-02-08 10:15:11

标签: c

我在结构中有一个指针字段,它指向结构实例的链接列表。

struct myStruct {
    some fields...
    struct list_objects * volatile list;
}

根据我的理解,我这样声明它是为了告诉编译器指针可以从其他线程更改,因此请不要缓存它。
list指向的内容不会改变,但指针会改变。 (否则,volatile必须是第一个关键字吗?)

list的访问受到互斥量的保护,因此线程不会在写入此指针时发生冲突。

当我将该指针的地址读入指向指针的指针时,会发生问题。

struct list_objects **ptrToPtr = &myStructVariable->list;

我需要双指针将另一个指针分配给该变量或遍历链表。

编译器发出“分配放弃易失性限定符”警告。我阅读了此警告,并认为我基本上理解了该警告,但我不明白为什么它会出现在这里。 此变量的地址永远不会更改。内容是易变的,但内容不可变。

我想我对此事认识不好。请帮我解决这个问题。

3 个答案:

答案 0 :(得分:4)

您是正确的,ptrToPtr不会更改(如果您未对其进行赋值),因此它不必是易变的。但是,*ptrToPtr可能会发生变化,因为它实际上是myStructVariable->list

因此,您的声明应为struct list_objects * volatile * ptrToPtr = &myStructVariable->list;

答案 1 :(得分:2)

在这种情况下,volatile确实是特定于指针的,并且您应该能够执行以下操作,例如在复制变量时丢弃限定符:

int* volatile vptr;
int* ptr = vptr;

就像我们可以将const int的值分配给int一样。

但是,这不是您的代码所要做的。它试图指向原始类型。为此,您需要一个“指向可变指针的指针”。您的情况是struct list_objects *volatile * ptrToPt(从右到左阅读)。

或者,也可以:

struct list_objects*  volatile vptr = ...;
struct list_objects*  ptr = vptr;
struct list_objects** pptr = &ptr;

但是请注意,这需要原始指针的副本,因此,如果原始指针发生更改,则ptr仍将包含旧地址。

答案 2 :(得分:1)

&myStructVariable->list是指向struct list_objects volatile指针的指针。

因此您需要将ptrToPtr声明为

struct list_objects *volatile *ptrToPtr;
//                   ^^^^^^^^