What is the meaning of void* volatile* in c++
Asked Answered
B

4

22

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?

Broomstick answered 28/11, 2014 at 3:48 Comment(4)
That seems valid but I am not sure how to read it, so that is why I asked.Broomstick
My guess for the downvote would be that someone only read the question title and assumed it was a no-research question about what void or volatile mean in isolation.Watteau
@vsoftco surely that's rather an over-estimate (amongst people following the c++ tag anyway) - volatile is commonly known and so is the meaning of simple pointer declarations , so even if this specific combination hadn't been seen before it can be worked outAdlei
@MattMcNabb agree, maybe I should've changed the percentage, but when you first bump into it, and someone asks you "tell me what the heck is this", I bet most people won't be able to respond in 5 seconds. Or maybe you would be able to, however I have to first remind myself what volatile means, then remind myself the multiple pointer definition stuff. But in any case, I wouldn't have downvoted such a question.Finsteraarhorn
S
21

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
Sprage answered 28/11, 2014 at 4:0 Comment(3)
quantdev, does volatile void even make sense? Or does it in casts?Finsteraarhorn
@vsoftco: it makes sense - you can add but not remove volatile during a static_cast (you'd need to also use const_cast), so ensuring the volatile void* is volatile helps prevent accidental removal of volatility when accessing the pointed-to object.Fur
volatile void makes sense if you assume that a void* doesn't point to a void, it points to something with a real type but you don't know which type. So "volatile void*" means "could be volatile int*, could be volatile double*, could be volatile some struct*..."Subaudition
F
10

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)

Fur answered 28/11, 2014 at 4:1 Comment(0)
A
7

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).

Adlei answered 28/11, 2014 at 5:25 Comment(0)
G
-1

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.
Gelding answered 4/3, 2018 at 23:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.