Re: Namespace vs. isnan
"Alberto Ganesh Barbati" <AlbertoBarbati@libero.it> wrote in message
news:vOyfj.214763$U01.1393855@twister1.libero.it...
Dave Steffen ha scritto:
Hi Folks,
I came across an annoying thing: the 'isnan' function isn't a
function, it's actually a macro (at least on my Linux system), defined
in math.h.
Correct, C99 requires isnan() to be a macro.
In principle, the notion was IIRC that #include <math.h> pulls the
contents of math.h into the global namespace (a la C), while <cmath>
pulls the contents into namespace std.
That is incorrect.
It's correct, just not complete.
First of all, the standard library of C++03 makes reference to the C
library of C90,
No, C95.
not of C99. I don't have C90 at hand, but I guess
isnan() was not present in C90. So, in order for this discussion to make
sense, we have to consider the next revision of C++, which makes
reference to C99 and mentions isnan() explicitly.
Or you can consider TR1, which already includes isnan a la C99.
It's not a required standard, but it is a widely supported Technical
Report. And most of it (including the isnan bit) has already been
voted into C++0X.
Please notice that in C++ <math.h> is defined in terms of <cmath> and
not viceversa.
In principle, but rarely in practice. C++0X has already accepted
current practice as future principle.
This means that the <math.h> in C++ may be different
from
the <math.h> in C, in the sense that they do not necessarily define the
same things (how this is achieved on a shared C/C++ implementation,
whether by using two different files, by relying on the pre-processor or
by any other mean, is unspecified).
Aside from some tinkering with a handful of function declarations, the
primary difference is that C++ disallows masking macros for C functions.
Actually, according to latest draft of C++0X, <cmath> shall define (in
namespace std) several things with the same meaning as in the C99
<math.h>, but *not* all of it and also adds several things. In
particular, <cmath> shall *not* define a macro named isnan() nor any of
the other is*() macros. On the contrary, isnan() is defined to be a
template.
Of course, you can't pull a macro (nasty things) into namespaces at
all. Does the standard say anything about what #include <cmath> does
to macros (he asks, expecting the answer 'no).
C++0X (which is not yet a standard!) says explicitly that <cmath> shall
not define is*() as macros but as templates in section 26.7/12:
Yes, this is an analytic continuation of the "no masking macros" rule
from C++98.
"The templates defined in <cmath> replace the C99 macros with the same
names. The templates have the following declarations:
namespace std {
template <class T> bool signbit(T x);
template <class T> int fpclassify(T x);
template <class T> bool isfinite(T x);
template <class T> bool isinf(T x);
template <class T> bool isnan(T x);
template <class T> bool isnormal(T x);
template <class T> bool isgreater(T x, T y);
template <class T> bool isgreaterequal(T x, T y);
template <class T> bool isless(T x, T y);
template <class T> bool islessequal(T x, T y);
template <class T> bool islessgreater(T x, T y);
template <class T> bool isunordered(T x, T y);
} // namespace std"
What I'd like to do is arrange for 'isnan' to actually act like a
function, so I can provide overloaded versions to handle some
locally-grown numeric types. One possibility:
#include <cmath>
namespace detail {
bool isNaN(double d) { return isnan(d); }
}
#undef isnan
namespace myNameSpace{
bool isnan(double d) { return detail::isNaN(d); }
}
// carry on using isnan on doubles and providing overloads for other
// things
Comments? Notions? Half-baked ideas? Thanks!
I don't know the rationale of providing templates rather than overloads.
There's a rather widespread practice of templatizing on floating-point
types. See, e.g. complex.
Anyway, C++0X achieves your goal without messing with macros.
Yes.
P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]