First, we have 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 );

```

Second, we have the compiler intrinsic, \_InterlockedExchange64(), note the absence of volatile;

<http://msdn.microsoft.com/en-us/library/1s26w950%28v=vs.80%29.aspx>

```
__int64 _InterlockedExchange64( __int64 * Target, __int64 Value );

```

Next, we have InterlockedExchangePointer() which like InterlockedExchange64(), uses 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 );

```

But now we come to the intrinsic for pointer exchange, \_InterlockedExchangePointer() and here we see volatile used!

<http://msdn.microsoft.com/en-us/library/853x471w.aspx>

```
void * _InterlockedExchangePointer( void * volatile * Target, void * Value );

```

The underlying instruction is the same in all cases, so what gives? documentation error?

The GCC instrincs don't mention volatile for exchange, but then they don't mention it for CAS either! so that doesn't help.

My view is that a CAS target is volatile, because you can only know at run time if the exchange will occur; but atomic exchange should not be volatile, because the target is always updated (even if it's value doesn't change), so the compiler has no uncertainty.

I see also the function for InterlockedIncrement() are volatile, but the instrincs are not. The intrinsics for CAS have volatile for their destinations.