6 c++ floating-point exception visual-c++
我遇到了在Visual Studio 2005中打开浮点异常的问题.如果我有这样的代码:
double d = 0.0;
double d2 = 3.0;
double d3 = d2/d;
Run Code Online (Sandbox Code Playgroud)
如果我注册一个SEH处理程序例程,那么我可以轻松地将div-by-zero转换为C++异常并捕获它.到现在为止还挺好.
但是,当我这样做时,第一个操作数(上例中的0.0)留在FPU寄存器堆栈上.如果我这样做了8次,那么从那时起我将开始从每个浮点操作获得一个浮点堆栈检查异常.
我可以使用__asm块来处理这个来执行FSTP,从而将杂散值从堆栈中弹出,一切都很好.
然而,这让我很担心,因为我没有在任何地方看到这个问题.我怎么能确定我应该弹出的值的数量?在异常时弹出堆栈中的所有内容是否安全?这个领域有推荐的最佳实践吗?
谢谢!
虽然我也找不到任何东西,但我可以对可能的答案给出一些解释:
ABI 定义在函数调用时堆栈应为空,并且在退出时应再次为空,除非返回的是浮点值(此时它将是堆栈上的唯一项)。
由于异常处理程序必须能够返回到任何位置,因此这些位置必须满足某些条件。这里的问题是,堆栈展开器是否了解具有 catch() 的函数的 FPU 堆栈?答案很可能是否定的,因为创建具有固定属性的合适返回点比在展开中包含完整的 FPU 堆栈更容易、更快捷。
这会导致你的问题 - 通常引发异常会让编译器处理 FPU 为空的情况,但在 SEH 处理程序中,编译器不知道它导致进入另一个函数,因此无法处理这些事情以防万一。(除了它又慢得可怕)
这意味着 FPU 堆栈很可能在返回时应处于“一致”状态,这意味着您可能需要相当于 EMMS 指令的指令。
为什么选择EMMS?好吧,除非不受支持,否则它会执行以下操作:
如果您想支持 Pentium 1 或更差的版本,您当然可以在 EMMS 周围使用 if() 并使用其他东西来代替。
当然不能保证,但我希望我充分解释了可能答案的原因。
归档时间: |
|
查看次数: |
2546 次 |
最近记录: |