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]
- For compatibility with the C standard library ...
- 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).- 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 namespacestd
.
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 #define
s 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
(likestdlib.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 formname.h
, behaves as if each name placed in the standard library namespace by the correspondingcname
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 namespacestd
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 headercname
shall be the same as that of the corresponding headername.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 namespacestd
. It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespacestd
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>
, andstd::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
When to Pass by Reference and When to Pass by Pointer in C++
Strongly Typed Using and Typedef
Why Should I Not Try to Use "This" Value After "Delete This"
Representing 128-Bit Numbers in C++
Constexpr If and Static_Assert
Assigning Parsers to Auto Variables
Standard Library Sort and User Defined Types
What Is the Worst Real-World Macros/Pre-Processor Abuse You'Ve Ever Come Across
Using Scanf() in C++ Programs Is Faster Than Using Cin
Confused When Boost::Asio::Io_Service Run Method Blocks/Unblocks
Why Class Data Members Can't Be Initialized by Direct Initialization Syntax
Prevent Static Initialization Order "Fiasco", C++
Avoiding Circular Dependencies of Header Files
Overload Resolution Between Object, Rvalue Reference, Const Reference