strict aliasing: how to swap pointers

Sergei Organov osv@javad.com
Wed Apr 30 09:03:00 GMT 2008


Evan Jones <evanj@MIT.EDU> writes:
> 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.

Violation (or not) of strict aliasing rules is *inside* the swap
function. It's at the time when you access objects the aliasing rules
apply, not at the time of conversion of pointer types. As you didn't
show the code of your exchange() function, it's impossible to say if you
violate strict aliasing or not, though I somehow feel you do.

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

I'd expect a function to swap two pointers to have prototype of the
form:

void exchange(void** p1, void** p2);

doing something like that:

{
  void* t = *p1;
  *p1 = *p2;
  *p2 = t;
}

However, your prototype is rather different.

Now, here is a solution that does not break strict aliasing rules:

$ cat alias.cc
#include <cstdio>
#include <cstring>

using namespace std;

void swap(void* p1, void* p2)
{
  void* t;
  memcpy(&t, p1, sizeof(t));
  memcpy(p1, p2, sizeof(t));
  memcpy(p2, &t, sizeof(t));
}

int main()
{
  int v1 = 42;
  int v2 = 123;
  int* a = &v1;
  int* b = &v2;
  int before = *a;
  swap(&a, &b);
  int after = *a;
  printf("before: %d after: %d\n", before, after);
  return 0;
}

$ g++-4.1  -O2 -W -Wall -o alias alias.cc
$ ./alias
before: 42 after: 123
$ 

Please note that GCC is capable to optimize-out memcpy() calls, so the
resulting code should be rather optimal.

-- Sergei.



More information about the Gcc-help mailing list