Fixing a floating point exception when operating on NaN


A customer had a DLL would sometimes fail to load into certain clients. Further investigation revealed that it failed to load into programs that had enabled floating point exceptions, perhaps inadvertently. The DLL initialized some global variables to hold convenient values, and one of the values it needed was NaN.

This particular DLL did not use the C++ standard library, so it did not have access to numeric_limits<double>::quiet_NaN(). (And even if it did, those values are not compile-time constants.) Instead, it tried to generate a NaN on its own:

double const NaN = HUGE_VAL * 0;

The gotcha here is that HUGE_VAL is a static global variable in the Microsoft C runtime, so this performs a runtime calculation inside of DLL_PROCESS_ATTACH, and if floating point exceptions are enabled, the NaN-generating calculation causes the exception to be raised, which then causes the loader to treat the DLL as having failed to initialize.

The DLL was precalculating NaN because there was a method that returns NaN to indicate that something isn't available. They precalculated the value so that that method could return it.

The customer's solution was to move the NaN-generating calculation into the code that needed it. Unfortunately, that still raises the "invalid calculation" exception in the case where the function wants to report "No value", which isn't really a case of an invalid calculation; it's just a sentinel value.

Instead, the code can generate a NaN at compile time. Everybody wins: There is no exception at DLL load time because there is no code running at DLL load time! It also means that the page containing the NaN variable does not get dirtied, which avoids a copy-on-write charge.

Comments (9)
  1. Rob Yull says:

    Just pointing out that since C++11 numeric_limits::quiet_NaN() can potentially be generated at compile-time, since it should be constexpr. (I know it doesn’t help in this example due to the DLL).

  2. I don’t really get the “@2016 Microsoft” in the footer. What does “@” mean in this context? Is it some kind of joke (replacing “©” by “@”)?

    1. Andreas — It might just be a typo. Microsoft gets it right on other pages (https://msdn.microsoft.com/en-US/ for example).

      1. Ivan K says:

        Also I think the ground rules or somewhere mentioned that the content of this blog doesn’t represent official Microsoft policy. And when you pointed it out I found the @ symbol kind of entertaining. Although I guess ms would have every to claim (c) if it wanted.

        1. Erik F says:

          Technically, you don’t need any copyright notice at all: copyright legislation in TRIPS and Berne Convention countries states that copyright begins with creation. You can register copyrights for legal reasons (say, if you want to establish priority) but it’s not required.

          (And I thought that a research paper that I wrote not long ago was kind of pointless information!) :-)

          1. smf says:

            America copyright law does seem to extend more protection if you include a notice.

            However I don’t believe “@ Microsoft” will help. You have to use the word Copyright or the symbol, (C) isn’t valid either.

  3. Medinoc says:

    HUGE_VAL * 0 is a NaN? Is there something missing here?

    1. Joshua says:

      Yeah. You miss HUGE_VAL = +INF.

  4. DWalker says:

    I don’t like in-band signaling (sentinel values to mean something)… but sometimes it may be unavoidable.

Comments are closed.

Skip to main content