Подтвердить что ты не робот

В чем смысл void * volatile * в С++

Я просматриваю следующий код:

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

и мне интересно, почему не просто a volatile void* в качестве аргумента. В общем, что такое семантика или определение a volatile*? Я также полагаю, что вы можете использовать квалификатор volatile* с любым другим типом, кроме void. Это правильно?

4b9b3361

Ответ 1

Используйте cdecl или правило по часовой стрелке, чтобы расшифровать объявления стиля C:

void* volatile* x
  • объявляет x как указатель на volatile указатель на void

который отличается от:

volatile void* x
  • объявить x как указатель на volatile void

Ответ 2

интересно, почему [ void* volatile* и] не просто volatile void*...?

Это разные вещи.

  • void* volatile* является указателем на volatile (void*) (поэтому разыменование и доступ к volatile void* возможно без кастинга, но просто даст вам адрес какой-то еще неизвестной вещи в памяти )

  • volatile void* является указателем на volatile void (так что вы должны использовать тип, например say volatile int* или volatile My_Class* перед разыменованием)

Ответ 3

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;, например, тогда *x имеет тип void * volatile, который имеет те же последствия, что мы только что рассмотрели для ptr2.

Компилятор будет жаловаться, если вы опустили квалификатор, например. void * *y = &ptr2;. Это связано с тем, что выражение *y будет иметь тип void * (энергонезависимый), поэтому компилятор может выполнять оптимизации вокруг него, однако это неправильное поведение, потому что ptr2 не разрешает эти оптимизации. (Вы можете признать, что "летучая правильность" - это то же самое, что и const-correctness).