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

Anonymous
  • 4,167
  • 11
  • 47
  • 52
  • 1
    What is your compiler - many compilers do not conform exactly – mmmmmm Jan 22 '10 at 15:50
  • I'm using the GNU.GCC compiler – Anonymous Jan 22 '10 at 15:53
  • Which version? 3.x is too old IIRC. – MSalters Jan 22 '10 at 16:00
  • 1
    Exact dupe of http://stackoverflow.com/questions/2116226/namespace-usage/2116289#2116289 asked here 6 hours ago. –  Jan 22 '10 at 16:06
  • 1
    @Neil: Doesn't look like an exact duplicate to me. The older question is about header namespaces in general, this one about where C header names go in namespaces. – David Thornley Jan 22 '10 at 16:16
  • @David "But why is this not needed for srand, rand and time ? I'm pretty sure they are in std, because if I try to specifically pour std:: in front of them, my code is working fine." looks like the same question to me. –  Jan 22 '10 at 16:28
  • I'm sorry if the questions are similar, though I think exact duplicate is strong wording. The title of the question was namespace usage, which even if I had seen the title of the topic I wouldn't have looked in it because of how vague it is. You obviously know about it because you answered the question. – Anonymous Jan 22 '10 at 16:36
  • In addition, the answers to this question provided a completely different set of information than the other question. StackOverflow has just gained a new flux of information for users to find. I can only see this as a benefit. – Anonymous Jan 22 '10 at 16:47

5 Answers5

9

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
  • 333,147
  • 50
  • 533
  • 760
  • So using style headers shouldn't hurt portability? – Anonymous Jan 22 '10 at 16:32
  • No, using `` 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 Jan 22 '10 at 16:35
  • 8
    I'm a weird sort of purist and will likely go on using the `` headers, but this is sad to know. – Omnifarious Jan 22 '10 at 16:40
6

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

mmmmmm
  • 32,227
  • 27
  • 88
  • 117
4

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
  • 879
  • 5
  • 6
1

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
  • 56,304
  • 9
  • 91
  • 158
0

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
  • 17,166
  • 1
  • 38
  • 51