Oct 022013
 

You might notice that when comparing with NaN, the comparison gives wrong results at least for x64 builds. Take a look at the following piece of code. If you run this sample application the comparison statement if(lfv==0.0) returns true and the MessageBox is displayed. (We had a customer who reported this behavior.)

#include "stdafx.h"
#include <limits>


int _tmain(int argc, _TCHAR* argv[])
{
    double lfv = std::numeric_limits<double>::quiet_NaN();

    if (lfv == 0.0)
        ::MessageBox(::GetActiveWindow(), _T("Equal"), argv[0], MB_OK);

    return 0;
}

If you put a breakpoint at the if statement, this is what the debugger shows as values for lfv. lfv is definitely not zero.

image

So why is the comparison behaving weird. The reason for this issue is that you’ve disable precise comparison of floating point values via the compiler switch /fp:fast. To fix this you should change to /fp:precise. This can be done via project properties dialog as well…

image

So you might ask why does it behave well for x86 builds? The answer is that comparing NaN’s with /fp:fast result in undefined behavior. So it is OK for the comparisons to behave differently on different targets with this option.

You should be aware of all the implications of using /fp:fast in VC++ and one of them is undefined behavior for NaN comparisons. This is the way VC++ specifies how /fp:fast behaves and is likely due to implementation constraints. Other compilers may produce the correct result for such compares but that is because each compiler has its own specification of what /fp:fast means.

Now you might think just for one comparison should I enable /fp;precise? The answer is that you can enable this feature per compilation unit or per function. Check out following link for details: http://msdn.microsoft.com/en-us/library/45ec64h6.aspx

The above link talks about the float_control pragma. So in order to fix above code we can do this instead of turning on /fp:precise for the entire project…

#include "stdafx.h"
#include <limits>

#pragma float_control(precise, on)

int _tmain(int argc, _TCHAR* argv[])
{
    double lfv = std::numeric_limits<double>::quiet_NaN();

    if (lfv == 0.0)
        ::MessageBox(::GetActiveWindow(), _T("Equal"), argv[0], MB_OK);

    return 0;
}
#pragma float_control(precise, off)

Or if you have too many functions you can enable /fp:precise per cpp file or per compilation unit. Right click on the cpp file, select properties and navigate to the following property and change it to /fp:precise

image

This should will help solve your comparison failures with NaN values.

Jan 092013
 

This hidden Visual C++ compiler switch will print out the full path of files included via #includes. You add this option likewise…

image

Sample output…

1>  Note: including file:  C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\include\afxwin.h
1>  Note: including file:   C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\include\afx.h
1>  Note: including file:    C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\new.h
1>  Note: including file:     C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\crtdefs.h
1>  Note: including file:      C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\sal.h

….

Jan 062012
 

What do we mean by intrinsic?

Most functions are contained in libraries, but some functions are built in (that is, intrinsic) to the compiler. These are referred to as intrinsic functions or intrinsics.

Taken from MSDN…

The __noop intrinsic specifies that a function should be ignored and the argument list be parsed but no code be generated for the arguments. It is intended for use in global debug functions that take a variable number of arguments.

The compiler converts the __noop intrinsic to 0 at compile time. The following code shows how you could use __noop.
 

// compiler_intrinsics__noop.cpp
// compile with or without /DDEBUG
#include <stdio.h>

#if DEBUG
   #define PRINT   printf_s
#else
   #define PRINT   __noop
#endif

int main()
{
   PRINT("\nhello\n");
}

So if you have custom macros which should expand to nought in release version the proper way to do this would be via __noop. Remember this is Microsoft(R) specific.