Why do C++11 CAS operations take two pointer parameters?

Many of the C++11 CAS operations (e.g., atomic_compare_exchange_weak, atomic_compare_exchange_strong) take two pointers and a value, i.e., like this:

bool atomic_compare_exchange(T* pointer, T* expected,       // pseudodeclaration!
                             T desired);

In contrast, the CAS operations from Microsoft, gcc, and Intel all take one pointer and two values:

long InterlockedCompareExchange(long* pointer, long desired,       // Microsoft
                                long expected);

int __sync_bool_compare_and_swap (T* pointer, T expected,          // gcc and
                                  T desired);                      // Intel

Why do the C++11 CAS functions take two pointers and a value instead of what appears to be a more conventional one pointer and two values?

Answers


The C++11 way is more useful: If the exchange fails, then *expected is updated to the new, current value. That makes it easy to use the function in a loop:

T value = x.load();
T newvalue = frob(value);

while (!atomic_compare_exchange(&x, &value, newvalue))
{
    newvalue = frob(value);
}

With the Microsoft signature, testing whether the operation succeeded is more cumbersome, and ditto for GCC's __sync_type version. With GCC's __sync_bool, you even need to perform another load each time the exchange fails.


Need Your Help

Jenkins build number issue

xml batch-file ant jenkins batch-processing

I have posted the question once but I think it was incomplete information.. Here is my question..I am new to jenkins. I am running a free-style project in jenkins. Previously I was using BuildForge...

Why is List<T>.IndexOf(T) returning -1 on object that exists?

c# .net asp.net-mvc collections

I have a foreach looping through a List of objects in an ASP.NET MVC/Razor project. I'm trying to use to index of the current object to determine if there is another object in the list.