Is isnan in the std:: namespace? More in general, when is std:: necessary, optional or to be avoided?

Antonio picture Antonio · Aug 8, 2013 · Viewed 16.6k times · Source

With Mingw 4.7.2, I have a library that doesn't compile because of a call to isnan. The compiler says "everything will be fine" if I use std::isnan, and indeed I manage to compile my file.

But if I check here (Edit: but maybe I should have checked also here :-) ), the std:: doesn't seem to be necessary. If I add it, will the file be portable?

More in general, for each case is there a general way to understand when putting std:: is necessary (for portability), optional or to be avoided?

Edit

Indeed among the origins of the problem is that there are multiple header inclusions, and some of the included headers include <cmath>, while this cpp file tries to include <math.h> (when <cmath> has already been included).

Answer

Christian Rau picture Christian Rau · Aug 8, 2013

It depends on which header you include. If you include the C header <math.h> (which is part of C++, albeit marked as deprecated), then you can use the unqualified C functions, like isnan. If you on the other hand include the C++ header <cmath>, you are only guaranteed that it brings all the functions from <math.h> into the std namespace and thus you have to properly qualify them, like std::isnan (or use some kind of using directive). Unfortunately an implementation is allowed but not required to bring those functions into the global namespace, too, when including <cmath> (and thus it is one of the many "works on my machine"-incidences of C++ and the reason why many people write code like you just tried to compile unsuccessfully).

So to sum up: Either include <math.h> and use isnan or include <cmath> and use std::isnan, everything else is non-portable. Of course all this applies to any other C header and its respective C++ version, too.

EDIT: It should be noted though, that this particular function isnan is only supported since C++11 and wasn't available in C++98 at all (which may be part of your confusion). But this doesn't change anything in this situation because in C++98 neither <cmath> nor <math.h> (which was the actual C89/C90 header back then and not the C99 header that C++11 includes) had this function, since they're always in-sync. So what this library from your question maybe tried was to use C++98 while taking the isnan function from a different C99 implementation (which isn't a particularly good idea, as it might conflict with the C89/C90 parts of the C++ implementation, never even tried this though).