首先,我们有 InterlockedExchange64();
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683593%28v=vs.85%29.aspx
LONGLONG __cdecl InterlockedExchange64( __inout LONGLONG volatile *Target, __in LONGLONG Value );
其次,我们有编译器内在函数 _InterlockedExchange64(),注意没有 volatile;
http://msdn.microsoft.com/en-us/library/1s26w950%28v=vs.80%29.aspx
__int64 _InterlockedExchange64( __int64 * Target, __int64 Value );
接下来,我们有 InterlockedExchangePointer(),它与 InterlockedExchange64() 一样,使用 volatile。
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683609%28v=vs.85%29.aspx
PVOID __cdecl InterlockedExchangePointer( __inout PVOID volatile *Target, __in PVOID Value );
但是现在我们来到了指针交换的内在函数 _InterlockedExchangePointer() ,在这里我们看到了 volatile 的使用!
http://msdn.microsoft.com/en-us/library/853x471w.aspx
void * _InterlockedExchangePointer( void * volatile * Target, void * Value );
底层指令在所有情况下都是相同的,那么给出了什么?文档错误?
GCC instrincs 没有提到 volatile 进行交换,但是他们也没有提到 CAS !所以这没有帮助。
我的观点是 CAS 目标是易变的,因为你只能在运行时知道交换是否会发生;但是原子交换不应该是易失的,因为目标总是更新的(即使它的值没有改变),所以编译器没有不确定性。
我还看到 InterlockedIncrement() 的函数是易变的,但 instrincs 不是。CAS 的内在函数对于它们的目的地来说是 volatile 的。