Что означает void * volatile* в C++
Я смотрю на следующий код:
inline void* interlocked_read_acquire(void* volatile* x);
и мне интересно, почему не просто volatile void*
в качестве аргумента. В общем, что такое семантика или определение a volatile*
? Я также делаю предположение, что вы можете использовать volatile*
квалификатор с любым другим типом, кроме пустоты. Это верно?
4 ответов
использовать ключевое слово cdecl или по часовой стрелке спиральное правило чтобы расшифровать объявления в стиле C:
void* volatile* x
- объявляет x как указатель на volatile указатель на void
который отличается от :
volatile void* x
- объявить x как указатель на volatile void
интересно почему [
void* volatile*
и не толькоvolatile void*
...?
это разные вещи.
void* volatile*
является указателем на volatile (void*
) (таким образом, разыменование и доступ кvolatile void*
возможно без кастинга, но просто даст вам адрес какой-то еще не определенной вещи в памяти)volatile void*
является указателем на volatilevoid
(так что вы должны привести к типу, как сказатьvolatile int*
илиvolatile My_Class*
прежде чем разыменование)
void * ptr1;
означает, что ptr1
- переменная, тип которой void *
. Этот тип указывает на "общий указатель" - он указывает на некоторую ячейку памяти, но не содержит информации о типе, что находится в этой ячейке.
void * volatile ptr2;
означает, что переменная ptr2
также является общим указателем, но ptr2
тоже volatile
. Ключевое слово volatile
называется cv-квалификатор и он имеет те же правила грамматики, что и const
.
значение Летучего переменная - это когда какой-то другой код говорит ptr2
, компилятор не может оптимизировать это; он должен прочитать или записать местоположение памяти, где ptr2
хранится; он должен учитывать возможность того, что какой-то внешний процесс также читает или записывает это местоположение.
наконец, void * volatile *x
это то, что может указывать на ptr2
. Например, мы могли бы void * volatile * x = &ptr2;
. Если мы пишем *x = NULL;
например,*x
типа void * volatile
что имеет те же последствия, что и мы просто посмотрел на ptr2
.
компилятор будет жаловаться, если вы пропустили квалификатор, например,void * *y = &ptr2;
. Это потому, что выражение *y
будет иметь тип void *
(энергонезависимый), поэтому компилятор может выполнять оптимизацию вокруг него, однако это неправильное поведение, потому что ptr2
не разрешает эти оптимизации. (Вы можете признать, что" изменчивая корректность " -это то же самое, что и const-корректность).
volatile является дополнительным свойством, вы можете сначала удалить его для чтения из
void* volatile* x
в:
void* *x
Это очень знакомо. Например, массив указателей памяти malloc-ed. И вы не будете путать с
volatile void*
, которая снижена до
void* x.