Intro: Im trying to quick hack fix old code and use __try MSVC extension to check if some ptr points to some legit memory or if *ptr will cause memory violation(if so I drop processing of this ptr). So I wrote something like:
bool checkIsPtrPointingToValidAddress(const void *ptr)
{
__try
{
auto cpy = *((int*)ptr); // force mem access...
if ( (cpy ==42) && ((rand()+rand()+rand()+rand()+ rand()) == 1))
{
FILE* pFile = fopen ("tempdata.dat","w"); //... by unlikely but possible action
fputs (" ",pFile);
fclose (pFile);
}
return true;
}
__except(1)
{
return false;
}
}
Thing is that my solution to force mem access seems weird, ugly, and as a bonus I'm not sure it is correct. Also please not I can't disable optimizations on the entire project, so that is not an option. And documentation for pragma optimize on MSDN sucks, aka it is not clear if "" disables all optimizations on the function.
First of all that's a pretty bad idea to begin with, so you may want to think the whole design over. But if you're forced to stick with it then something like:
should certainly do the trick. The compiler can't eliminate the reads or assume that they are identical so has to execute the code. On the other hand assuming no threading problems or other interesting scenarios we know that the two reads will be identical so not cause the exception to be thrown.
Added
By the rules of the standard, any read from or write to a volatile object constitutes observable behaviour (a.k.a. side effect), so even the following should be enough:
This includes a write into the volatile object
copy
, so it cannot be optimised away.