Evan Jones wrote: > Rupert Wood wrote: >> I don't know how to fight aliasing rules but as another approach you >> could template the function instead, i.e. >> >> template<typename T> T* exchange(T** ptr, T* next); >> >> exchange<int>(&a, &v2); >> >> since you're using C++ here. > > I initially dismissed this solution since the implementation of exchange > is either a typical swap using a temporary, a compare-and-swap sequence > or a mutex, depending on various compilation options. I wanted to avoid > including the implementation in the header to avoid a bunch of #ifdefs. > However, your email made me try to avoid the warning with a template > wrapper: > > > template <typename T> > T* exchange_template(T** ptr, T* next) { > return reinterpret_cast<T*>( > exchange(reinterpret_cast<void**>(ptr), next)); > } > > ... > > exchange_template(&a, &v2); > > > I don't understand why, but this compiles without warnings. It also > avoids needing to look up the aliasing rules, and places the dangerous > cast in a single location, so this seems like a better solution. > > I would still like to know if my original solution is "correct" or not, > since it would be needed for C. We have no way to know, since you didn't provide us with the source of exchange(), and that's where the aliasing violation, if any, would occur. However, the answer is almost certainly no. I don't know why you're trying to do something so simple in such a difficult way. If you really want to do this in standard portable C, the easiest way is a macro: #define SWAP(TYPE, A, B) do { TYPE tmp = a; b = b; b = tmp; } while (0) You can't portably cast a pointer to an int* to a pointer to a void* and then dereference the resulting pointers since the things they point to might not even be the same size. The union hack will work on gcc, though. Andrew.