When Using C Headers in C++, Should We Use Functions from Std:: or the Global Namespace

When using C headers in C++, should we use functions from std:: or the global namespace?

From the C++11 Standard (emphasis mine):

D.5 C standard library headers [depr.c.headers]

  1. For compatibility with the C standard library ...
  2. Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard
    library namespace by the corresponding cname header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).
  3. Example: The header <cstdlib> assuredly provides its declarations and definitions within the namespace
    std
    . It may also provide these names within the global namespace. The header <stdlib.h> assuredly provides the same declarations and definitions within the global namespace, much as in the C Standard. It
    may also provide these names within the namespace std.

Using the «name.h» headers is deprecated, they have been identified as candidates for removal from future revisions.

So, I would suggest to include the «cname» headers and to use the declarations and definitions from the std namespace.

If you have to use the «name.h» headers for some reasons (it's deprecated, see above), I would suggest to use the declarations and definitions from the global namespace.

In other words: prefer

#include <cstdio>

int main() {
std::printf("Hello world\n");
}

over

#include <stdio.h>

int main() {
printf("Hello world\n");
}

Are C keywords/functions not enclosed in std namespace in C++?

The standard says that when you include any standard include file it is possible that this will include other include files. It is implementation dependent which ones and how many of them.

The implication is that your code simply must not define any global name that is also standard.

I can understand this seems a difficult requirement (indeed it is) and also that makes one wonder why there are standard include files at all and we don't have simply the whole standard available instead (that's a good question). But none the less this is the situation.

Situation is even worse with POSIX where not only random names are reserved, but also quite a lot prefixes and suffixes; for example code that use any name starting with LC_ followed by an uppercase letter in any way is possibly clashing with #defines related to locale support. Any name that ends with _t is also reserved, not joking. The list is huge.

As a general rule try to define the least possible amount of global names and avoid anything that is also used by the standard library. Even when "it works" on your compiler, your program may find the problem when ported to another compiler (or the next version of the same compiler). Avoiding defining global names makes also easier for your code to be integrated in larger programs with code written by others. Ideally your code should just have one global name (a namespace, a single class or a single function)... unfortunately with C++ you cannot get below that.

Something I remember bumping in when writing small C++ experiments when I usually don't care about these name clashing problems is for example y0 that is a standard Bessel function (this is not a joke; there is a global standard function double y0(double) and any program that uses y0 for anything else at global level is not a valid C++ program).

When using standard C functions in C++, is the std:: prefix required?

The C++ library includes the same definitions as the C language
library organized in the same structure of header files, with the
following differences:

  • Each header file has the same name as the C language version but with a "c" prefix and no extension. For example, the C++ equivalent
    for the C language header file <stdlib.h> is <cstdlib>.
  • Every element of the library is defined within the std namespace.

Nevertheless, for compatibility with C, the traditional header names
name.h (like stdlib.h) are also provided with the same definitions
within the global namespace although its use is deprecated in C++.

(source)

The std:: part of the std::printf() call is the standard way to use names in the standard library, therefore, I suggest to use it.

Why do we need to specify namespace if we also need to include standard library headers?

Generally namespaces prevent name clashes between different modules or libraries. Now you might say that the std namespace is the standard that everyone uses so nobody should name their variables, classes or functions to clash with the standard.

But that is short sighted. What is used in todays standard is not the same as yesterdays standard or tomorrows standard. The standard changes and things are added over time (and sometimes removed). So any variable, class or function you use today could have a name clash tomorrow.

Having the namespace std avoids that problem because it will never clash with anything you define outside the namespace std.

Plus std::... automatically tells me where to find the documentation when I see some unknown thing and tells me it's not something thought up by the project I'm looking at.

Is it ok to qualify C functions with the `std` namespace?

If you use e.g. <math.h>

No, you shouldn't.

It is unspecified whether they are available in the namespace std on any particular implementation:

[C++11: D.5/2]: Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).

However, you should not be using this header:

[C++11: C.3.1/1]: For compatibility with the Standard C library, the C++ standard library provides the 18 C headers (D.5), but their use is deprecated in C++.


If you use e.g. <cmath>

Yes, you should.

It is unspecified whether they are available in the global namespace on any particular implementation:

[C++11: 17.6.1.2/4]: Except as noted in Clauses 18 through 30 and Annex D, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in the C standard library (1.2) or the C Unicode TR, as appropriate, as if by inclusion. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope (3.3.6) of the namespace std. 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 (7.3.3).

When the C++ standard provides C headers bringing names into the global namespace, does that include overloads?

Yes, all overloads should be brought into the global namespace. My understanding is that the math.h header is intended to look something like:

// math.h:
#include <cmath>

using std::abs;
// etc.

So, yes: the behavior of your example program is different when compiled as a C program than when compiled as a C++ program. As a C++ program, it will call std::abs(double) from <math.h>. As a C program it will call abs(int) from <stdlib.h> (this is the only abs function in the C Standard Library, since C does not support function overloading).

are C functions declared in c____ headers guaranteed to be in the global namespace as well as std?

Here's a nice synopsis of the situation (with some relaity vs. what the standard says) from Stephan T. Lavavej of the MSVC team (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 headers from the C Standard Library, which is hilarious.)

I've never been fond of the <cfoo> headers myself, and found that I've always use <foo.h>. Now I feel like I can stop being anxious about my lack of C++ 'purity' in that regard.

Can I include a headerfile in a namespace?

System header files like <conio.h> which are intended to be used in both C and C++ will enclose their declarations in an extern C scope, forcing C linkage for all that is contained in them, regardless of whatever additional C++ namespaces you add. That’s why your code compiles in this case.

See also this, which is almost a duplicate of this question, but not exactly.

In short, yes it’s valid, but I would strongly encourage against it. There are many other ways to solve this problem, like creating wrapper modules for the functions you want to have alternate symbols for.

As a side note: try putting your own getch in an extern C block. My guess is you’ll get a linker error.

Can I stop GCC including standard library names into the global namespace?

The rule is that #include <xxx.h> (where xxx.h is the name of a standard C header) is required to define all the names required by the C standard for that header in the global namespace, and is allowed to also define those names (with the same meaning) in namespace std. Similarly, #include <cxxx> (where cxxx is the name of one of the standard C++ headers for the standard C library) is required to define all the names from the corresponding C header (with the same meaning) in the namespace std, and is allowed to also define those names in the global namespace.

Back in C++ 98 those headers were not allowed to add names to the other namespace. Some compiler couldn't do that. For example, if the C++ library writers don't control the C headers, the usual implementation technique is for the C++ header to #include the C header and hoist the C names into std with using declarations. So the rule was changed to reflect reality.

The language definition does not require those headers to put the names in both places; if it did, then the cxxx headers wouldn't be needed.

In short, you can't count on #include <cxxx> putting C names into the global namespace, but you also can't count on it not putting them there.

using namespace in c++ headers

You should definitely NOT use using namespace in headers for precisely the reason you say, that it can unexpectedly change the meaning of code in any other files that include that header. There's no way to undo a using namespace which is another reason it's so dangerous. I typically just use grep or the like to make sure that using namespace isn't being called out in headers rather than trying anything more complicated. Probably static code checkers flag this too.

The header should include just the headers that it needs to compile. An easy way to enforce this is to always include each source file's own header as the first thing, before any other headers. Then the source file will fail to compile if the header isn't self-contained. In some cases, for example referring to implementation-detail classes within a library, you can use forward declarations instead of #include because you have full control over the definition of such forward declared class.

I'm not sure I would call it common, but it definitely shows up once in a while, usually written by new programmers that aren't aware of the negative consequences. Typically just a little education about the risks takes care of any issues since it's relatively simple to fix.



Related Topics



Leave a reply



Submit