NoS*_*tAl 2 c++ seh dead-code compiler-optimization visual-c++
简介:我试图快速破解修复旧代码并使用__try MSVC扩展来检查某些ptr是否指向某些合法内存,或者*ptr是否会导致内存违规(如果是这样我放弃处理此ptr).所以我写了类似的东西:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
事实是我强制mem访问的解决方案看起来很奇怪,丑陋,作为奖励,我不确定它是否正确.另外请不要我不能禁用整个项目的优化,所以这不是一个选项.在MSDN上进行pragma优化的文档很糟糕,也就是说""是否禁用该函数的所有优化还不清楚.
Voo*_*Voo 10
首先,这是一个非常糟糕的主意,所以你可能想要考虑整个设计.但如果你被迫坚持下去,那就像:
volatile auto copy1 = *((char*)ptr); // using int* here could lead to aliasing violations, so better char in the general case..
volatile auto copy1 = *((char*)ptr);
if (copy1 != copy2)
throw std::exception("Cannot happen, but compiler cannot know this");
Run Code Online (Sandbox Code Playgroud)
当然应该这样做.编译器不能消除读取或假设它们是相同的,因此必须执行代码.另一方面,假设没有线程问题或其他有趣的场景,我们知道两个读取将是相同的,因此不会导致抛出异常.
添加
根据标准的规则,对易失性对象的任何读取或写入构成可观察的行为(也称为副作用),因此即使以下内容也应该足够:
volatile auto copy = *((char*)ptr);
Run Code Online (Sandbox Code Playgroud)
这包括写入volatile对象copy,因此无法进行优化.