namespace issues with old C headers

David Schultz das@FreeBSD.ORG
Tue Apr 1 11:26:00 GMT 2003


>From what I gather from the C++ standard[1], when one includes an
old-style header such as <math.h>, all of the symbols specified in
the C standard are supposed to appear in the global namespace.
When <cmath> is included instead, these symbols are supposed to
appear in the std namespace, except for macros, which may appear
in the global namespace.

In libstdc++[2], <cmath> has some clever tricks to put macros
defined in C99 in the std namespace instead.  This means that
everything works fine when you include <cmath>, and everything
works fine when you include <math.h>, but things break when you
include both.  Specifically, <math.h> no longer puts macros things
in the global namespace as expected because <cmath> has already
included <math.h> and undef'd the macros.

It seems sort of silly to include both until you realize that some
new-style headers such as <locale> indirectly include <cmath>.  I
can't say that it's a good idea to mix old- and new-style headers,
but there are programs out there that do it, which don't compile
anymore.  OpenSceneGraph and fractorama are two examples, which
fail due to being unable to find isnan() in the global namespace
after including <math.h>.

I'm seeing this problem with FreeBSD's math.h[3], starting when we
added C99 support.  However, I see no evidence that glibc would be
any different with regards to this issue.  In C99, isnan() is
defined to be a macro so that it can take arguments of multiple
floating-point types in a language that does not support
overloading.  The relevant bits are:

	#ifndef _MATH_H_
	#define	_MATH_H_
	[...]
	#define	isnan(x)	[...]
	[...]
	#endif

If you look at <cmath>, you'll see why this is a problem.  Here
are some possible solutions:

(A)	Don't play tricks with C99 macros in <cmath>.  I think
	this approach would be fine by the C++ standard, but
	someone with a copy should check.

(B)	Ameliorate the problem by getting rid of promiscuous
	includes of <cmath> in other headers.

(C)	Change <math.h> to redefine macros even if it has already
	been included earlier.  This is a kludge, and I'd rather
	not have to do it.

I could be off-base, but it looks to me like (A) would be the best
way to go, and doing (B) would be nice for other reasons.  I would
appreciate comments and suggestions about this from gcc-land.  TIA.


[1] A secondary source, actually.

[2] I'm looking at gcc 3.2.2, but I don't see any progress on
    this issue in the latest CVS version.

[3] http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/msun/src/math.h?rev=HEAD



More information about the Libstdc++ mailing list