0

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.

littleadv
  • 20,100
  • 2
  • 36
  • 50
Seb
  • 3,414
  • 10
  • 73
  • 106
  • I'm sorry, but what does InterlockedCompareExchangePointer return? – Monkeyanator Dec 12 '11 at 00:18
  • it's the usual CAS idiom: `CAS(storage, new_val, expected_old_val)` which returns the old value found in location `storage` -- http://msdn.microsoft.com/en-us/library/windows/desktop/ms683568%28v=vs.85%29.aspx – Jason S Dec 12 '11 at 00:21
  • Hey I am not sure about this, but I doubt if you can convert a non-volatile variable into volatile in a function call. Try making the original pointer volatile and see if it works? – Ankit Dec 12 '11 at 00:22
  • 1
    @Ankit: it's the other way round: you can go from nonvolatile to volatile safely, but not the other way safely. – Jason S Dec 12 '11 at 00:28

3 Answers3

3

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.

littleadv
  • 20,100
  • 2
  • 36
  • 50
1

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.

Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
0

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.

tpg2114
  • 14,112
  • 6
  • 42
  • 57