I have a function to swap any two pointers (assuming that sizeof(void*)
== sizeof(T*)). I would like to use it without violating strict aliasing
rules. I have a workaround, but I would like to verify that this is the
right way to do this.
The test case:
void* exchange(void** ptr, void* next);
int main() {
int v1 = 42;
int v2 = 123;
int* a = &v1;
int before = *a;
exchange(reinterpret_cast<void**>(&a), &v2);
int after = *a;
printf("before: %d after: %d\n", before, after);
return 0;
}
Output from Redhat's version of gcc 4.1.2 20070925:
test.cc: In function ‘int main()’:
test.cc:16: warning: dereferencing type-punned pointer will break
strict-aliasing rules
The output from the program is correct. My workaround avoids the
warning, but I think it will still permit GCC to generate undesired
optimizations, since it says nothing about the *values* pointed to:
union {
int** int_ptr;
void** void_ptr;
} temp = { &a };
exchange(temp.void_ptr, &v2);
I believe this may be incorrect, since *int_ptr and *void_ptr have
distinct types, and hence GCC could decide that they cannot possibly be
aliases? What is the "right" way to fix this? Thanks for your help,
Evan Jones
--
Evan Jones
http://evanjones.ca/