tags:

views:

115

answers:

5

The C++ Programming Language : Special Edition states on page 431 that...

For every header < X.h > defining part of the C standard library in the global namespace and also in namespace std, there is a header < cX > defining the same names in the std namespace only.

However, when I use C headers in the < cX > style, I don't need to qualify the namespace. For example...

#include <cmath>
void f() {
  double var = sqrt( 17 );
}

This would compile fine. Even though the book says that using the < cX > header defines names in the std namespace only, you are allowed to use those names without qualifying the namespace. What am I missing here?

P.S. Using the GNU.GCC compiler

A: 

You are probably missing using a standards-conformant compiler (or the one you use is configured to be compatible with pre-standard code).

Pontus Gagge
+1  A: 

Why do you say "This would compile fine" when it violates the Standard? Who allows you to use those names without qualifying the namespace? Have you tested this on a particular implementation and found that it works?

I strongly advise against using some particular non-standard feature because it happens to work on your compiler of choice. Such things break easily, perhaps with a later version of the same compiler.

David Thornley
+1 Works != should be expected to work.
Chris Lutz
+6  A: 

The rule for the C libraries differs from C++ libraries for namespaces

gcc interprets the standard in Gcc docs as

The standard specifies that if one includes the C-style header (<math.h> in this case), the symbols will be available in the global namespace and perhaps in namespace std:: (but this is no longer a firm requirement.) One the other hand, including the C++-style header (<cmath>) guarantees that the entities will be found in namespace std and perhaps in the global namespace.

In the draft C0X++ spec it says in section 17.6.2.3 Headers

It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations

Mark
+4  A: 

It's hard to fix this without implementing the C library twice. See DR 456, which basically proposes giving up on the problem.

P-Nuts
+1 for linking to the DR.
David Thornley
+3  A: 

Stephan T. Lavavej, a member of the MSVC team, addresses the reality of this situation (and some of the refinements to the standard) in this comment on one of his blog postings (http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359):

> also, <cstddef>, <cstdlib>, and std::size_t etc should be used!

I used to be very careful about that. C++98 had a splendid dream wherein <cfoo> would declare everything within namespace std, and <foo.h> would include <cfoo> and then drag everything into the global namespace with using-declarations. (This is D.5 [depr.c.headers].)

This was ignored by lots of implementers (some of which had very little control over the C Standard Library headers). So, C++0x has been changed to match reality. As of the N2723 Working Paper, http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf , now <cfoo> is guaranteed to declare everything within namespace std, and may or may not declare things within the global namespace. <foo.h> is the opposite: it is guaranteed to declare everything within the global namespace, and may or may not declare things within namespace std.

In reality and in C++0x, including <cfoo> is no safeguard against everything getting declared in the global namespace anyways. That's why I'm ceasing to bother with <cfoo>.

This was Library Issue 456, http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456 .

(C++0x still deprecates the <foo.h> headers from the C Standard Library, which is hilarious.)

I'm in 100% agreement with Lavavej, except I never tried to be very careful about using the <cfoo> style headers even when I first started using C++ - the standard C ones were just too ingrained - and there was never any real world problem using them (and apparently there was never any real world benefit to using the <cfoo> style headers).

Michael Burr
So using <cfoo> style headers shouldn't hurt portability?
Anonymous
No, using `<cfoo>` headers shouldn't hurt portability. You just shouldn't count on the names from that header being excluded from the global namespace. Because in reality there's a very good chance they'll be there anyway.
Michael Burr
I'm a weird sort of purist and will likely go on using the `<cfoo>` headers, but this is sad to know.
Omnifarious