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:
- Just before running the clients' dll, switching on floating point introspection.
- Run client code.
- Check for any problems.
- 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:
- Is the documentation correct, or is the warning (I'm betting on the warning)?
- Is there a reliable and safe way of doing this?
- Should I be doing this at all, or is it just too dangerous?
You tried
That's not how it works. It's a compiler directive, and it means
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:
_controlfp_s