Casting a pointer to a volatile void** in C++ - c++

I have fairly decent C++ skills, but this one cast has been giving me issues. I have a function that takes in the following parameters: (volatile void **, void * , void*). I have 3 int* variables and I am trying to pass them in as (&var1, var2, var3). However, I am getting the following error: Cannot convert parameter 1 from int** to volatile void**. Is there a specific cast that needs to be made to allow for this? Below is a snippet of code that I am using. Any help is greatly appreciated.
int* pVal = InterlockedCompareExchangePointer(&cur_val, new_val, old_val);
This is being done in VS2010 on a windows XP machine.

The first one should be volatile void ** and you have int **. You can either just cast to volatile void**, or (better) declare the original variable as volatile and then cast.
volatile means that the variable can be changed elsewhere outside of your code, and basically it means that the variable won't be optimized, but since your original variable is not defined as volatile it might still be optimized, and you would get incorrect results.

You can do a const_cast, but the best thing you can do is to declare your variable a volatile int* (i.e. pointer to volatile int) because otherwise the result might be undefined.
InterlockedCompareExchangePointer does an operation that may be beyond the optimizer's scope to analyze, so it's important that the variable is volatile to make sure its value is fetched from memory (and not cached in registers etc.) each time it is being used.

In addition to declaring the int as volatile, you still need to cast it as:
int* pVal = (int *)InterlockedCompareExchangePointer((void **)&cur_val, (void *)new_val, (void *)old_val);
Note the cast of the value returned from the function too. It returns a void *, so it must be cast to int *.
C++ requires explicit casts.

Related

How do I receive a volatile through a pointer-to-non-volatile?

I'm working with an API that gives me a pointer for memory-mapped I/O. It does this by filling in a pointer-to-pointer argument:
int map(void** p);
Because this is memory mapped I/O, I'm pretty sure I should be using volatile here. (I don't know why they didn't make the parameter a volatile void**.)
But, my volatile void** isn't implicitly convertible to the function's void**, so I can't just pass it in directly:
volatile void* p;
map(&p); // Error: no known conversion from 'volatile void **' to 'void **'.
I'm currently working around this with an extra variable and a separate assignment step:
volatile void* p;
void* pNonVolatile;
map(&pNonVolatile);
p = pNonVolatile;
This seems verbose. Is it safe in this case to instead cast the volatile away when passing the pointer in? i.e.
volatile void* p;
map(const_cast<void**>(&p));
From a C++ language point of view, this could result in undefined behavior in the library, but not in your code using const_cast.
However, from what you have described, the library probably does not use C or C++ to write into this memory space (you mentioned it uses memory-mapped I/O). So the undefined behavior which could exist if the library dereferenced your pointer without volatile is not relevant, because hardware is doing that, not software.
In any case, whether you use const_cast or the "extra pointer then assign" solution doesn't seem to matter. They should be both OK if the memory is written by a hardware device, but not OK if it's written by the library without volatile.

What scenario might require the use \ need of const pointer to (non-const\const) data

I understand the concept of final in Java or const in C++ for forcing constant values and allowing the compiler to enforce that on anyone using the modules you write.
I am not able to see where would you want to have a const pointer, why would you not want the pointer to change regardless of the data being constant or not:
e.g
why this?
char greetings[] = "Hello";
char * const p = greetings; // const pointer, non-const data
const char * const p = greetings; // const pointer and const data
I cannot visualize an exmaple where you want to keep the pointer const, could it be for a file handle or something similar? or just a pointer to an object you don't want to change?
You may want to make a pointer itself constant for several reasons:
Helping others understand your code - When you declare a pointer and make it constant, you tell the readers that there are no changes done to that pointer in the rest of your function, so they would have a better idea of how you use the pointer.
Helping others maintain your code - Someone else who maintains your code after you will have better idea of what you expected to do with the pointer. If he tries to pass a non-constant reference or a pointer to the pointer that you declared const, the compiler is going to catch this error.
Enable compiler optimizations - When compilers see something declared const, they can optimize more aggressively.

C/C++: casting away volatile considered harmful?

(related to this question Is It Safe to Cast Away volatile?, but not quite the same, as that question relates to a specific instance)
Is there ever a case where casting away volatile is not considered a dangerous practice?
(one particular example: if there is a function declared
void foo(long *pl);
and I have to implement
void bar(volatile long *pl);
with part of my implementation requiring bar() to call foo(pl), then it seems like I can't get this to work as is, because the assumptions made by the compilation of foo() and the compilation of the caller of bar() are incompatible.)
As a corollary, if I have a volatile variable v, and I want to call foo(&v) with someone else's function void foo(long *pl), and that person tells me it's safe, I can just cast the pointer before the call, my instinct is to tell them they're wrong because there's no way to guarantee that, and that they should change the declaration to void foo(volatile long *pl) if they want to support the use of volatile variables. Which one of us is correct?
If the variable is declared volatile then it is undefined behaviour to cast away the volatile, just as it is undefined behaviour to cast away the const from a variable declared const. See Annex J.2 of the C Standard:
The behavior is undefined in the following circumstances:
...
— An attempt is made to modify an object defined with a const-qualified type through
use of an lvalue with non-const-qualified type (6.7.3).
— An attempt is made to refer to an object defined with a volatile-qualified type through
use of an lvalue with non-volatile-qualified type (6.7.3).
If, however, you just have a volatile pointer or a volatile reference to a non-volatile variable then you can freely cast away volatile.
volatile int i=0;
int j=0;
volatile int* pvi=&i; // ok
volatile int* pvj=&j; // ok can take a volatile pointer to a non-volatile object
int* pi=const_cast<int*>(pvi); // Danger Will Robinson! casting away true volatile
int* pj=const_cast<volatile int*>(pvj); // OK
*pi=3; // undefined behaviour, non-volatile access to volatile variable
*pj=3; // OK, j is not volatile
Casting away volatile would be ok, once the value is in fact no longer volatile. In SMP/multi-threading situations, this could become true after acquiring a lock (and passing a memory barrier, which is most often implicit in acquiring the lock).
So a typical pattern for this would be
volatile long *pl = /*...*/;
//
{
Lock scope(m_BigLock); /// acquire lock
long *p1nv = const_cast<long *>(p1);
// do work
} // release lock and forget about p1nv!
But I could come up with a number of other scenarios in which values stop being volatile. I won't suggest them here, as I'm sure you can come up with them yourself, if you know what you're doing. Otherwise, the locking scenarios seems solid enough to provide as an example
With a signature of foo(long *pl), the programmer is declaring that they are not expecting the pointed-to long value to change externally during the execution of foo. Passing a pointer to a long value that is being concurrently modified throughout an invocation might even lead to erroneous behavior if the compiler emits code that dereferences the pointer multiple times due to lack of registers and by it choosing not to store the value of the first dereference on the stack. For example, in:
void foo(long *pl) {
char *buf = (char *) malloc((size_t) *pl);
// ... busy work ...
// Now zero out buf:
long l;
for (l = 0; l < *pl; ++l) {
buf[l] = 0;
}
free(buf);
}
foo could overrun the buffer in the "zero out buf" step if the long value is increased while the busy work is being performed.
If the foo() function is supposed to atomically increment the long value pointed to by pl, then it would be incorrect for the function to take long *pl and not volatile long *pl because the function clearly requires that accesses of the long value be a sequence point. If foo() only atomically incremented, the function might work, but it would not be correct.
Two solutions to this problem have already been suggested in comments:
Wrap foo taking long * in an overload taking volatile long *:
inline void foo(volatile long *pvl) {
long l = *pvl;
foo(&l);
*pvl = l;
}
Change the declaration of foo to void foo(volatile long *pvl).

What is void* and to what variables/objects it can point to

Specifically, can it point to int/float etc.?
What about objects like NSString and the like?
Any examples will be greatly appreciated.
void* is such a pointer, that any pointer can be implicitly converted to void*.
For example;
int* p = new int;
void* pv = p; //OK;
p = pv; //Error, the opposite conversion must be explicit in C++ (in C this is OK too)
Also note that pointers to const cannot be converted to void* without a const_cast
E.g.
const int * pc = new const int(4);
void * pv = pc; //Error
const void* pcv = pc; //OK
Hth.
In C any pointer can point to any address in memory, as the type information is in the pointer, not in the target. So an int* is just a pointer to some memory location, which is believed to be an integer. A void* pointer, is just a pointer to a memory location where the type is not defined (could be anything).
Thus any pointer can be cast to void*, but not the other way around, because casting (for example) a void pointer to an int pointer is adding information to it - by performing the cast, you are declaring that the target data is integer, so naturally you have to explicitly say this. The other way around, all you are doing is saying that the int pointer is some kind of pointer, which is fine.
It's probably the same in C++.
A void * can point at any data-like thing in memory, like an integer value, a struct, or whatever.
Do note, however, that you cannot freely convert between void * and function pointers. This is because on some architectures, code is not in the same address space as data, and thus it's possible that address 0x00000000 for code refers to a different set of bits than address 0x00000000 for data does.
It would be possible to implement the compiler so that void * is large enough to remember the difference, but in general I think this is not done, instead the language leaves it undefined.
On typical/mainstream computers, code and data reside in the same address space, and then the compilers typically generate sensible results if you do store a function pointer into a void *, since it can be quite useful.
Besides everything else that was already said by the other users, a void* it's commonly used in callback definitions. This allows your callback to receive user data of any type, including your own defined objects/structs, which should be casted to the appropriate type before using it:
void my_player_cb(int reason, void* data)
{
Player_t* player = (Player_t*)data;
if (reason == END_OF_FILE)
{
if (player->playing)
{
// execute stop(), release allocated resources and
// start() playing the next file on the list
}
}
}
void* can point to an address in memory but the syntax has no type-information. you can cast it to any pointer-type you want but it is your responsibility that that type matches the semantics of the data.

Is It Safe to Cast Away volatile?

Most of the time, I am doing this way.
class a {
public:
~ a() {
i = 100; // OK
delete (int *)j; // Compiler happy. But, is it safe?
// The following code will lead compilation error : delete j;
}
private:
volatile int i;
volatile int *j;
};
int main() {
a aa;
}
However, I saw an article here:
https://www.securecoding.cert.org/confluence/display/seccode/EXP32-C.+Do+not+access+a+volatile+object+through+a+non-volatile+reference
Casting away volatile allows access to
an object through a non-volatile
reference. This can result in
undefined and perhaps unintended
program behavior.
So, what will be the workaround for my above code example?
Here is the error message I get if I use
delete j
Note that, this is output from VC6 (Don't ask why I am using VC6!)
c:\projects\a\a.cpp(5) : error C2664:
'delete' : cannot convert parameter 1
from 'volatile int *' to 'void *'
Conversion loses qualifiers
Nothing. If you don't access the volatile memory, the semantics of volatile are unaffected. If you accessed volatile memory through a casted non-volatile pointer, the compiler might optimize the reference away. If the value had changed, you'd have the wrong value. For some value of wrong. ;-)
The delete doesn't access the volatile memory, it just frees it. Sort of an uncommon thing to do with volatile memory.
deleteing a volatile would imply that you've serialized access to it so it is not, in fact, volatile any more. The proper way to remove the volatile (once you know it's safe) is with const_cast<int*>.
If the pointer, and not the int, is volatile, then you really meant int *volatile j. Moreover, if all the members of a class are volatile, you probably want to qualify the entire object at once, a volatile aa;.
It depends on the meaning you expect from your volatile variable. Right now, j is a pointer to a volatile integer; is that what you mean? If so, it's safe since you don't need to access the volatile value, just its address, which isn't volatile.
If, however, you meant that you want a volatile pointer to an integer, the required syntax is int* volatile j. In that case, it could be problematic to cast it to a non-volatile pointer first, but I don't think your compiler would complain if you tried to delete it as is. G++, for one, doesn't.
That should be fine, since you're not accessing the variable after casting away the volatile. However, I don't know why you'd get an error regardless. I tried that code myself, and everything seemed to go fine, what did you see happen?