我已经在这里的房子周围走走了,我以为我找到了解决方案。当然,它似乎可以正确识别我所知道的问题,但是在大约一半的系统测试用例中,也会导致无法解释的崩溃。

问题在于我们的代码需要将客户端代码作为dll调用。我们可以控制我们的代码,但不能控制客户的代码,经验表明,他们的代码并不总是完美无缺的。我通过退出程序以清楚地指出可能出了什么问题的方式来防止分段错误,但是我也有一些来自客户端代码的除零异常,我想识别并然后退出。

我一直想做的是:

  • 在运行客户端的dll之前,打开浮点
    内省(introspection)。
  • 运行客户端代码。
  • 检查是否有问题。
  • 关闭自省(introspection)速度。

  • 理论上,有很多方法可以做到这一点,但是许多方法似乎不适用于VS2010。

    我一直在尝试使用float_point编译指示:
    #pragma float_control(except, on, push)
    
    // run client code
    
    #pragma float_control(pop)
    
    __asm fwait;    // This forces the floating point unit to synchronise
    if (_statusfp() & _SW_ZERODIVIDE)
    {
        // abort the program
    }
    

    从理论上讲这应该是可以的,并且在实践中50%的时间效果很好。

    我认为问题可能是因为float_point控件保持打开状态,并在代码的其他地方引起了问题。

    根据microsoft.com:



    但是,在编译过程中,我得到警告:



    从表面上看这是直接矛盾。

    所以我的问题是:
  • 文档是否正确,还是警告(我押在警告上)?
  • 有可靠且安全的方法吗?
  • 我应该完全这样做吗,还是太危险了?
  • 最佳答案

    你试过了

    #pragma float_control(except, on, push)
    
    // run client code
    
    #pragma float_control(pop)
    

    那不是它的工作原理。这是一个编译器指令,这意味着
    #pragma float_control(except, on, push)
    
    // This entire function is compiled with float_control exceptions on.
    // Therefore, the pragma has to appear outside the function, at global scope.
    
    #pragma float_control(pop)
    

    当然,此设置仅影响正在编译的函数,而不会影响它们可能调用的任何函数-例如您的客户端。 #pragma无法更改已编译的代码。

    因此,答案是:
  • 都是正确的
  • 是, _controlfp_s
  • 您缺少SSE2状态,因此至少是不完整的
  • 08-17 03:25