views:

67

answers:

2

I have a function that takes a unsigned long* and needs to pass it to a external library that takes a unsigned int* and on this platform unsigned int/long are the same size.

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibAtomicUpdateVar((unsigned int*)var); // lib atomically updates variable
}

This generate a warning saying that its breaking strict-aliasing rules. Are there any work arounds?

Thank you

Edit: I apologize for not being clear. The code is an atomic update so going around the library to store it is not an option. I could drop down to assembly but I'd like to do this in C++.

+2  A: 

This should work:

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibUpdateVar(reinterpret_cast<unsigned int*>(var));
}
identity
dangerous if sizeof(long) != sizeof(int)
nos
He said in the original post that they were guaranteed to be the same size on his platform. But yes, you are right.
identity
+1. Under certain conditions, this is actually appropriate in my opinion. But it really depends on the case and I'd feel more comfortable with some sort of `sizeof(int)==sizeof(long)` check in the program that makes compilation fail in case the condition is not met -- C++0x's `static_cast` anyone? :-)
sellibitze
I use a macro like this to do static asserts:#define static_assert(x) extern char static_assert[(x) ? 1 : -1]
dave
I do a static_assert in my code but I don't see how this fixes the aliasing problem.
coderdave
+7  A: 
void UpdateVar(unsigned long* var) {
   unsigned int x = static_cast<unsigned int>(*var);
   ExternalLibUpdateVar(&x);
   *var = static_cast<unsigned long>(x);
}
dave
Make that `static_cast`s, and I'd up-vote.
sbi
Sorry; didn't notice the C++ tag
dave
What is the real difference between `static_cast` and `reinterpret_cast` in this case?
identity
Now that's something different. Imagin that `ExternalLibUpdate` stores the passed address somewhere. It would store the address of the local `x`, not the address in `var`.
Johannes Schaub - litb
http://blogs.msdn.com/b/oldnewthing/archive/2006/03/20/555511.aspx
dave
@IceDane I believe the behavior of reinterpret_cast here would be undefined -- as far as I know the only thing that's guaranteed is if you reinterpret_cast to a larger type then back again you'll get the original value back
dave
I edited my original post to reflect that the external lib is an atomic update so I'm not allowed to go around it to store it myself.
coderdave
You should properly @address people in comment replies, otherwise they don't see your replies in their responses tab. I only came by here by accident. Anyway, up-voted now.
sbi