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?

4
  • That seems valid but I am not sure how to read it, so that is why I asked. Commented Nov 28, 2014 at 3:56
  • 1
    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. Commented Nov 28, 2014 at 4:03
  • 2
    @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 out Commented Nov 28, 2014 at 5:15
  • @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. Commented Nov 28, 2014 at 5:16

4 Answers 4

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
Sign up to request clarification or add additional context in comments.

3 Comments

quantdev, does volatile void even make sense? Or does it in casts?
@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.
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*..."
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)

Comments

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

Comments

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.