I'm porting code written under Visual Studio 2012 to compile with Visual Studio 2015. The code builds OK with Windows 2012.
I have an issue with some code that calls InterlockedIncrement64
. It builds OK for an x64 target, but fails where the target is Win32 and the calling code is managed (i.e. compiled with /clr
), yielding:
error C3861: 'InterlockedIncrement64': identifier not found
Looking in winnt.h, it seems that InterlockedIncrement64
is undefined when the target is Win32 and _MANAGED
is defined.
I can rearrange the code such that InterlockedIncrement64
isn't called for managed code, but I'm still curious to know why this change in behavior has come with Visual Studio 2015.
As the name implies, InterlockedIncrement64
is an atomic increment operation for a LONGLONG
, and it needs memory to be 64 bit aligned.
Given that you can't set memory alignment in managed code and it may be used for managed class members then this limitation makes sense (to me): "...otherwise, this function will behave unpredictably on multiprocessor x86 systems and any non-x86 systems.". Think about this:
::InterlockedIncrement64(&_memberVariable);
If _memberVariable
is allocated in managed world, then it won't be 64-bit aligned (though it may happen by chance), and this code will always fail for Win32. It's simpler to remove this function when _MANAGED
is defined.
Workaround: check #ifdef _MANAGED
and call Interlocked::Increment
instead, or drop atomicity (!) but include a memory barrier after increment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With