Непонятная причина присвоения сбрасывает изменчивый классификатор - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть поле указателя в структуре, которое указывает на связанный список экземпляров структуры.

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

Согласно моему пониманию, я объявляю это так, чтобы сообщить компилятору, что указатель может измениться из других потоков.так что не кешируйте его.
Изменится не то, на что указывает list, а указатель.(иначе volatile должно быть первым ключевым словом, верно?)

Доступ к list защищен мьютексом, поэтому потоки не сталкиваются при записи в этот указатель.

При чтении возникает проблемаадрес этого указателя в указатель на указатель.

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

Мне нужен двойной указатель, чтобы назначить другой указатель на эту переменную или пройтись по связанному списку.

Компилятор выдает «назначение отбрасываетЛетучий классификатор "Предупреждение.Я читал об этом предупреждении и думаю, что в основном понял его, но не понимаю, почему оно появляется здесь.
Адрес этой переменной никогда не должен изменяться.Содержимое изменчиво, но не место, где оно находится.

Полагаю, у меня плохое понимание этого вопроса.Пожалуйста, помогите мне разобраться с этим.

Ответы [ 3 ]

0 голосов
/ 08 февраля 2019

&myStructVariable->list - указатель на энергозависимый указатель до struct list_objects.

Так что вам нужно объявить ptrToPtr как

struct list_objects *volatile *ptrToPtr;
//                   ^^^^^^^^
0 голосов
/ 08 февраля 2019

Это правда, что 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 будет по-прежнему содержать старый адрес.

0 голосов
/ 08 февраля 2019

Вы правы, что ptrToPtr не изменится (если вы не выполняете назначения), поэтому оно не должно быть изменчивым.Тем не менее, *ptrToPtr может измениться, потому что это фактически myStructVariable->list.

Таким образом, ваша декларация должна быть struct list_objects * volatile * ptrToPtr = &myStructVariable->list;.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...