Question

I've sort of gone around the houses here, and I'd thought I'd found a solution. It certainly seems to correctly identify the problems I know about, but also leads to unexplained crashes in about half of all system test cases.

The problem is that our code needs to call client code as a dll. We have control over our code, but not the clients', and experience has shown that their code isn't always flawless. I have protected against segmentation faults by exiting the program with a clear message of what might have been going wrong, but I've also had a few divide-by-zero exceptions coming from the clients' code, which I would like to identify and then exit.

What I've been wanting to do is:

  1. Just before running the clients' dll, switching on floating point introspection.
  2. Run client code.
  3. Check for any problems.
  4. Switch off introspection for speed.

There is theoretically a number of ways of doing this, but many don't seem to work for VS2010.

I have been trying to use the 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
}

This should be OK in theory, and in practice it works well 50% of the time.

I'm thinking that the problem might be the floating_point control stays on, and causes problems elsewhere in the code.

According to microsoft.com:

"The /fp:precise, /fp:fast, /fp:strict and /fp:except switches control floating-point semantics on a file-by-file basis. The float_control pragma provides such control on a function-by-function basis."

However, during compilation I get the warning:

warning C4177: #pragma 'float_control' should only be used at global scope or namespace scope

Which on the face of it is a direct contradiction.

So my question is:

  1. Is the documentation correct, or is the warning (I'm betting on the warning)?
  2. Is there a reliable and safe way of doing this?
  3. Should I be doing this at all, or is it just too dangerous?
Was it helpful?

Solution

You tried

#pragma float_control(except, on, push)

// run client code

#pragma float_control(pop)

That's not how it works. It's a compiler directive, and it means

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

And of course, this setting affects only the function(s) being compiled, no any functions that they may call - such as your clients. There is no way that a #pragma can change already compiled code.

So, the answers:

  1. Both are correct
  2. Yes, _controlfp_s
  3. You're missing the SSE2 status, so it's at least incomplete
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top