Intel® C++ Compiler - Floating point calculations produce NaNs with C code

If you have a C language function that is incorrectly prototyped or is not prototyped at all, the function may return a floating point value of possibly unexpected precision (single, double, or double extended precision), and which may corrupt the x87 floating point stack, which can produce NaN (Not-a-Number). Using consistent 
function prototypes will avoid this problem. Note, it is not necessary to consume the return value to avoid this problem (for example, by assigning the return value to a floating point variable). The only requirement is that the compiler knows, via the correct prototype, that the function does indeed return a floating point value.

The cause of this problem is due to corruption of the x87 FPU Data Register Stack, which consists of eight 80-bit rotating registers. Normally, on exiting a function that returns a floating point value, the FPU Stack should have exactly one element that is the return value. If the compiler knows a value is being returned, the value is popped from the Stack and the Stack is left empty, which is the correct state. However, if no prototype exists to show that the function returns a value, the value returned by the function remains on the Stack, and the Stack becomes unbalanced. In this case, if the function is called repeatedly, eventually register wraparound will occur and the FPU will detect a Stack overflow condition.

When the x87 FPU detects this particular Stack overflow condition, the x87 FPU sets the Stack Fault Flag (SF), the Invalid Operation Exception Flag (IE) and the C1 condition code flag of the x87 FPU Status Word to 1. If the IE exception is masked in the FPU Control Word, then no exception is generated and the application may be unaware of this condition. In this case, the only indication to the application will be the appearance of a NaN in the computation.

On Windows* platforms, a NaN will print as "-1.#IO".
On Linux* or Mac OS* X platforms, a NaN will print as "nan".

The Intel C++ compiler will also print the following warning message, if it cannot find a correct prototype for a C function that has a non-void return type:

warning #266: function declared implicitly

This problem can only occur for a C language function. It cannot occur for a C++ function, as correct prototypes are required to be declared for successful compilation and linking.

Note: The 8.0 and above compilers have a new compiler option -fpstkchk (Linux and Mac OS X) or /Qfpstkchk (Windows) to detect this problem and terminate the application. This option has been changed for 11.0 and later to -fp-stack-check (Linux and Mac OS X), /Qfp-stack-check (Windows). p>

For more complete information about compiler optimizations, see our Optimization Notice.