4

I'm trying to write a program which uses std::isnan() with MSVC 2010. I include cmath but unfortunately the compiler returns the error:

isnan is not part of the std namespace

Does MSVC 2010 support this function from std (AKA C++11)?

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
Igor
  • 5,620
  • 11
  • 51
  • 103
  • 1
    MSVC 2010 is not very C++11 complaint. Their most compliant version is 2015. – NathanOliver Jul 18 '16 at 16:28
  • @NathanOliver, unfortunately at the moment I'm stuck with 2010. Any hint on the fix? – Igor Jul 18 '16 at 16:29
  • @BatCoder, nothing to post. I just wrote `if( std::isnan( x ) )` and got aforementioned error. – Igor Jul 18 '16 at 16:30
  • 1
    [this](http://stackoverflow.com/questions/2249110/how-do-i-make-a-portable-isnan-isinf-function) may help. Can you use boost? – NathanOliver Jul 18 '16 at 16:34
  • 1
    How about `x != x`? – lorro Jul 18 '16 at 16:35
  • 3
    It was not standard in 2010, so it is called [`_isnan`](https://msdn.microsoft.com/en-us/library/tzthab44(v=vs.100).aspx) – Bo Persson Jul 18 '16 at 17:09
  • @Igor To add an explanation to the solution `x != x`: if a float is NaN, then it always compares false to an equality comparison, even if compared to NaN. Since a float `x` usually always compares equal to itself, if `x == x` is false, then `x` must be NaN. But you probably should use `_isnan` – KABoissonneault Jul 18 '16 at 17:12
  • [VS2010 to present C++ Standard support matrix](https://msdn.microsoft.com/en-us/library/hh567368.aspx). Basically which versions of VS support what portions of what standards. – user4581301 Jul 18 '16 at 17:41
  • To add to what @BoPersson said, `_isnan()` is defined in ``, and by extension in ``. – Justin Time - Reinstate Monica Jul 18 '16 at 18:27
  • I would also recommend looking out for other "gotchas" in VS 2010's implementation of C++0x, such as `char16_t` and `char32_t`; in VS 2010, they're actually defined as `typedef unsigned short char16_t;` and `typedef unsigned int char32_t;`. In general, VS 2010 can _handle_ most C++11 code (notable exceptions being uniform initialisation & variadic templates), but it isn't actually _compliant_ with as much of C++11 as you would expect, and uses some wonky hacks to mimic some of the features it doesn't actually support yet to keep valid code from breaking. – Justin Time - Reinstate Monica Jul 18 '16 at 18:30

2 Answers2

5

std::isnan is in <cmath> : http://en.cppreference.com/w/cpp/numeric/math/isnan

Your problem is probably VS2010 which has very poor C++11 support. I'd recommend grabbing VS2015 which is much better in that regard.

As can be seen here VS2010 only has _isnan .

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
  • as I wrote above, for now I'm stuck with 2010. Any hint on the fix? – Igor Jul 18 '16 at 16:32
  • This does not really answer the question. That isnan is in c++11 according to your link says nothing about msvc2010 having it. – André Jul 18 '16 at 19:12
  • Edited my answer to add a link to a page showing VS2010 only has _isnan. Btw; this stuff is highly googlable. – Jesper Juhl Jul 18 '16 at 19:17
3

Unfortunately, Visual Studio's C++11 support hasn't been that complete until the 2015 version, so you won't be able to utilize the C++ std::isnan functionality. Interestingly, there is a C99 isnan macro, but it's implementation defined and VS 2010 does not seem to have any of those macros. Fortunately though, the MS line of compilers do have their MS specific _ versions of the _isnan functionality. So you could write your own isnan as such:

#include <iostream>
#include <cmath>
#include <cfloat>
#include <limits>

namespace non_std
{

    template < typename T >
    bool isnan(T val)
    {
        #if defined(_WIN64)
            // x64 version
            return _isnanf(val) != 0;
        #else
            return _isnan(val) != 0;
        #endif
    }

}

int main(int argc, char** argv)
{
    float value = 1.0f;
    std::cout << value << " is " <<
        (non_std::isnan(value) ? "NaN" : "NOT NaN") << std::endl;

    if (std::numeric_limits<float>::has_quiet_NaN) {
        value = std::numeric_limits<float>::quiet_NaN();
        std::cout << value << " is " <<
            (non_std::isnan(value) ? "NaN" : "NOT NaN") << std::endl;
    }

    return 0;
}

On my machine this produces the output:

1 is NOT NaN

1.#QNAN is NaN

Note that the _isnanf is for 64-bit applications and the _WIN64 macro might not necessarily be defined, so if you target 64 bit be sure to adjust that.

Hope that can help.

txtechhelp
  • 6,625
  • 1
  • 30
  • 39