Re: strict aliasing: how to swap pointers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Evan Jones <evanj@xxxxxxx> 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.


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux