Reputation: 434
I have a pointer field in a struct that points to a linked list of struct instances.
struct myStruct {
some fields...
struct list_objects * volatile list;
}
According to my understanding I declare it like that to tell the compiler the pointer can change from other threads, so don't cache it.
Not the content of what list
points to will change but the pointer will change. (otherwise volatile must be the first keyword right?)
Access to list
is protected with a mutex so threads don't collide writing to this pointer.
A problem occurs when I read this pointer's address into a pointer to pointer.
struct list_objects **ptrToPtr = &myStructVariable->list;
I need the double pointer to assign another pointer into this variable or to walk the linked list.
The compiler issues a "assignment discards volatile qualifier" warning. I read about this warning and think I basically understood it but I don't understand why it appears here.
The address of this variable should never change. The content is volatile, but not the place where this content resides.
I guess I have a bad understanding of this matter. Please help me to sort this out.
Upvotes: 1
Views: 439
Reputation: 213306
It is true that the volatile
in this case is specific to the pointer and you should be able to do things like discarding the qualifier when copying the variable:
int* volatile vptr;
int* ptr = vptr;
Just as we can assign the value of a const int
to an int
.
However, that's not what your code does. It tries to point at the original type. For that you need a "pointer to volatile pointer to type". In your case this would be struct list_objects *volatile * ptrToPt
(read right-to-left).
Alternatively, this would be fine too:
struct list_objects* volatile vptr = ...;
struct list_objects* ptr = vptr;
struct list_objects** pptr = &ptr;
But note that this take a copy of the original pointer, so if the original changes, then ptr
will still contain the old address.
Upvotes: 2
Reputation: 30709
&myStructVariable->list
is a pointer to a volatile pointer to struct list_objects
.
So you need to declare ptrToPtr
as
struct list_objects *volatile *ptrToPtr;
// ^^^^^^^^
Upvotes: 1
Reputation: 222302
You are correct that ptrToPtr
will not change (if you perform no assignment to it), so it does not need to be volatile. However, *ptrToPtr
may change, because it is effectively myStructVariable->list
.
So your declaration should be struct list_objects * volatile * ptrToPtr = &myStructVariable->list;
.
Upvotes: 4