On Mac OS X and Windows there are builtin CompareAndSwap functions you should be using anyway (InterlockedCompareExchange() and OSAtomicCompareAndSwapPtrBarrier() respectively). Thus will work regardless of the compilers on those platforms.
On other Unixes it is a bit trickier, if you are using GCC 4.1 or later you can just use its builtin __sync_val_compare_and_swap(), and many though not all unix compilers support reasonable gcc extensions since a lot of code originating on Linux assumes they are present.
So if you want to wrap them up in a way that works with most all compilers for all processors on OS X and Windows, and with GCC and some other compilers on other platforms you should do something like:
boolean CompareAndSwapPointer(volatile * void * ptr,
void * new_value,
void * old_value) {
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
return OSAtomicCompareAndSwapPtr (old_value, new_value, ptr);
#elif defined(_MSC_VER)
return InterlockedCompareExchange(ptr, new_value, old_value);
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
return __sync_val_compare_and_swap(ptr, old_value, new_value);
#else
# error No implementation
#endif
}
That is not tested, but I think it should be correct. Note how all the OS libraries take the args in different orders ;-)
Obviously you can do a few version for the different size compare and swaps and wrap them in templates if you want. The APIs are mostly C based and encode the type information into the functions in such a way that it is sort of nasty for people used to parameterizing types via templates.
atomic_compare_exchange_*
family of functions is now in both<stdatomic.h>
in the C standard library and<atomic>
in the C++ standard library. – Magnum