Почему С++ 11 CAS выполняет два параметра указателя?

Многие из операций CAS 11 CAS (например, atomic_compare_exchange_weak, atomic_compare_exchange_strong) принимают два указателя и значение, то есть следующее:

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

В отличие от операций CAS от Microsoft, gcc и Intel все берут один указатель и два значения:

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

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

Почему С++ 11 CAS-функции принимают два указателя и значение вместо того, что кажется более обычным одним указателем и двумя значениями?

Ответ 1

Путь к С++ 11 более полезен: если обмен не выполняется, тогда *expected обновляется до нового текущего значения. Это упрощает использование функции в цикле:

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

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

С подписью Microsoft проверка того, была ли операция успешной, является более громоздкой, а также для версии GCC __sync_type. С помощью GCC __sync_bool вам даже нужно выполнять другую нагрузку каждый раз, когда происходит сбой обмена.

Ответ 2

Я не понимаю, почему у вас не было бы обоих. В моем случае использования версия С++ менее полезна. Я хочу подождать, пока переменная имеет некоторое значение, тогда я хочу установить ее в новое значение.

С GCC instrinsics:

while (!__sync_bool_compare_and_swap(&value, expected, desired)) { }

С С++ 11:

auto tmp = expected;
while (!value.compare_exchange_weak(tmp,desired)) 
{
  tmp = expected;
}