Что означает 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.