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:
volatile auto copy1 = *((char*)ptr); // using int* here could lead to aliasing violations, so better char in the general case..
volatile auto copy2 = *((char*)ptr);
if (copy1 != copy2)
throw std::exception("Cannot happen, but compiler cannot know this");
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:
volatile auto copy = *((char*)ptr);
This includes a write into the volatile object copy
, so it cannot be optimised away.
The Windows API has
BOOL WINAPI IsBadReadPtr(_In_ const VOID *lp,_In_ UINT_PTR ucb);
BOOL WINAPI IsBadWritePtr(_In_ LPVOID lp, _In_ UINT_PTR ucb);
You need to read the remarks section, but your case may be simple enough that these functions may suffice. Regardless the remarks section gives some helpful advice when trying to handle unsafe pointers yourself.
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