I’ve written optimistic thread-synchronization routines lots of times before, but today, the pattern that I’ve used for years now generates a warning in recent versions of VC++ (using VS 2022, v17.9.5):
static volatile int32_t _value;
...
void UpdateValueAtomically(...)
{
int32_t oldValue, newValue;
do {
oldValue = _value;
newValue = /* ... calculate newValue from oldValue ... */ ;
} while (InterlockedCompareExchange(&_value, newValue, oldValue) != oldValue);
}
In VC++, this now generates warning C28112 on the read of oldValue = _value
, complaining that _value
ought to be used only with Interlocked*()
APIs. There is, of course, no InterlockedRead()
, but oldValue = InterlockedCompareExchange(&_value, 0, 0)
could be used as an ugly equivalent; but I’m not convinced it’s necessary.
Is VC++ correct in telling me there’s an issue with the existing code that I’ve never noticed before? Is there a race condition here I’ve always missed until now? Or is VC++ warning about a problem that isn’t actually there?