1

我已经绕着这里的房子走了一圈,我以为我找到了解决办法。它似乎可以正确识别我所知道的问题,但也会导致大约一半的系统测试用例出现无法解释的崩溃。

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

我一直想做的是:

  1. 就在运行客户端的 dll 之前,打开浮点自检。
  2. 运行客户端代码。
  3. 检查是否有任何问题。
  4. 关闭内省以提高速度。

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

我一直在尝试使用 floating_point pragma:

#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:

“/fp:precise、/fp:fast、/fp:strict 和 /fp:except 开关在逐个文件的基础上控制浮点语义。float_control pragma 在逐个函数的基础上提供这种控制。”

但是,在编译期间,我收到警告:

警告 C4177:#pragma 'float_control' 只能在全局范围或命名空间范围内使用

从表面上看,这是一个直接的矛盾。

所以我的问题是:

  1. 文档是否正确,还是警告(我打赌警告)?
  2. 有没有可靠和安全的方法来做到这一点?
  3. 我应该这样做,还是太危险了?
4

1 回答 1

2

你试过

#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 无法更改已编译的代码。

所以,答案:

  1. 两者都是正确的
  2. 是的,_controlfp_s
  3. 您缺少 SSE2 状态,因此它至少不完整
于 2013-12-12T14:29:45.650 回答