What is the meaning of void* volatile* in c++

5.9k Views Asked by At

I am looking at the following code:

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

and am wondering why not just a volatile void* as an argument. In general what is the semantics or definition of a volatile*? I am also making the assumption that you could use the volatile* qualifier with any other type besides void. Is that correct?

4

There are 4 best solutions below

3
On BEST ANSWER

Use cdecl or the clockwise spiral rule to decipher C-style declarations :

void* volatile* x
  • declares x as pointer to volatile pointer to void

which is different from :

volatile void* x
  • declare x as pointer to volatile void
0
On

void * ptr1; means that ptr1 is a variable whose type is void *. This type indicates a "generic pointer" - it points to some memory location but contains no type information what what is in that location.

void * volatile ptr2; means that the variable ptr2 is also a generic pointer, but ptr2 is also volatile. The keyword volatile is called a cv-qualifier and it has the same grammar rules as const.

The meaning of a volatile variable is that when some other code says ptr2, the compiler cannot optimize that out; it must read or write the memory location where ptr2 is stored; it must allow for the possibility that some external process is also reading or writing that location.

Finally, void * volatile *x is something that can point to ptr2. For example we could have void * volatile * x = &ptr2; . If we then write *x = NULL; for example, then *x has type void * volatile which has the same implications as we just looked at for ptr2.

The compiler would complain if you omitted the qualifier, e.g. void * *y = &ptr2; . This is because the expression *y would then have type void * (non-volatile) so the compiler might perform optimizations around it, however this is incorrect behaviour because ptr2 does not permit those optimizations. (You may recognize that "volatile-correctness" is the same sort of thing as const-correctness).

0
On

wondering why [void* volatile* and] not just a volatile void*...?

They're different things.

  • void* volatile* is a pointer to a volatile (void*) (so dereferencing and accessing the volatile void* is possible without casting, but would just give you the address of some as-yet unspecified thing in memory)

  • volatile void* is a pointer to a volatile void (so you must cast to a type like say volatile int* or volatile My_Class* before dereferencing)

0
On

volatile is an add-on property, you can first remove it to read from

void* volatile* x

to:

void* *x

This is very familiar. For example, an array of malloc-ed memory pointers. And you won't get confused with

volatile void*

which is reduced to

void* x.