C++ language standard says in 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).
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. —end example ]
This seems to state rather explicitly ("... each name ...", "...the same declarations...") that the old-style <name.h> headers must provide the same set of declarations as the new-style <cname> headers, but in global namespace. No exception is made for C++-specific overloaded versions of various C functions, for one example.
That appears to mean that <math.h> must provide three versions of sin function: sin(float), sin(double) and sin(long double) in global namespace. This, in turn, means that the following C++ code should fail overload resolution
#include <math.h>
int main() {
sin(1);
}
It does fail under MSVC++ compiler, but it compiles successfully under GCC and Clang. So, does GCC just ignore the standard requirement with regard to deprecated old-style headers? Or do I somehow misinterpret the wording in the standard?
Thanks to #hvd's comments I have seen the light, it turns out MSVC is correct and GCC should be complaining about the ambiguity as well.
The only differences between including <cmath> vs <math.h> are where the names are originally scoped, which is in namespace std for the former, and the global namespace for the latter (implementations are free to provide the names in the other namespace as well, but this isn't mandated), and the fact that including the .h variants of C headers is deprecated.
Related
How come this piece of code doesn't need std namespace.
#include <stdio.h>
int main()
{
printf("Hello World");
return 0;
}
Because you included a C header, not a C++ header.
[library.c/1]: The C++ standard library also makes available the facilities of the C standard library, suitably adjusted to ensure static type safety.
[depr.c.headers.other/1]: Every C header other than <complex.h>, <iso646.h>, <stdalign.h>, <stdbool.h>, and <tgmath.h>, 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, except for the functions described in [sf.cmath], the declaration of std::byte ([cstddef.syn]), and the functions and function templates described in [support.types.byteops]. [..] It is unspecified whether these names are first declared or defined within namespace scope ([basic.scope.namespace]) of the namespace std and are then injected into the global namespace scope by explicit using-declarations ([namespace.udecl]).
The last bolded part above says that you may have been able to use std::printf as well, but that there is no guarantee of that.
Also note that the header is deprecated:
[diff.mods.to.headers/1]: For compatibility with the C standard library, the C++ standard library provides the C headers enumerated in [depr.c.headers], but their use is deprecated in C++.
On the flip side of the coin, if you'd included cstdio instead, you'd be guaranteed to get std::printf but the availability of ::printf (the fully-qualified name of the global symbol you used) would not be guaranteed:
[headers/4]: Except as noted in [library] through [thread] and [depr], the contents of each header cname is the same as that of the corresponding header name.h as specified in the C standard library. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope of the namespace std. It is unspecified whether these names (including any overloads added in [language.support] through [thread] and [depr]) are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations ([namespace.udecl]).
Short version:
C headers like stdio.h are in the global namespace, and possibly also in std;
C++ headers like cstdio are in the namespace std, and possibly also in the global namespace.
You only need using namespace std or std:: when you're using the namespace std,
The stdio.h header file allows you to use additional methods in the standard library that do not exist in all C++ code by default. By adding the line #include , you are instructing the compiler to copy the declarations in that header file into your code so you have access to them.
The line using namespace std allows you to utilize methods in the standard namespace without having to call out the standard name space each time. This helps eliminate typos, but could introduce other errors (if two namespaces have the same method signature).
For example,
#include <iostream>
std::cout << "Hello World!" << std::endl;
Could be written as:
#include <iostream>
using namespace std;
cout << "Hello World!" << endl;
using namespace std makes names from the standard namespace visible in your namespace.
stdio.h i a header that doesn't use its own namespace but instead puts its functions (e.g. printf) etc. in the namespace in which you include it (in your case the global namespace). Therefore you can access them directly.
Note that including headers in a namespace is not generally recommended (see first comment for an example), I only mentioned it for the sake of completeness since it might not be obvious for a beginner that the placement of the include makes a difference.
Time and again I run into problems from namespace pollution due to indirect inclusion of C-header files from C++ standard headers. For example, on my linux system gcc's (version 5.1.1) <thread> includes usr/include/bits/sched.h, which declares
extern "C" {
extern int clone(int (*__fn) (void *__arg), void *__child_stack, int __flags, void *__arg, ...) throw();
}
In the following minimal example
#include <thread> // indirect inclusion of <sched.h>
namespace {
struct foo
{ virtual foo*clone() const=0; };
foo*clone(std::unique_ptr<foo> const&); // function intended
struct bar : foo
{
std::unique_ptr<foo> daughter;
bar(foo*d) : daughter(d) {}
foo*clone() const
{ return new bar(::clone(daughter)); } // to be called here
};
}
the compiler complains about the call to ::clone() not matching the definition from bits/sched.h (ignoring the definition just before). (Note that simply calling clone instead of ::clone clashes with the member.)
So, the questions are:
Is gcc correct to discard my version of clone() when trying to resolve the function call ::clone(daughter)?
Is the pollution of the global namespace in this way standard compliant?
In the above example, can I resolve the problem without renaming my clone() functions (or the anonymous namespace) but still including <thread>?
Is gcc correct to discard my version of clone() when trying to resolve the function call ::clone(daughter)?
Yes, I think so.
Is the pollution of the global namespace in this way standard compliant?
It's arguable. For a pure C++ implementation, no, but there aren't many of them. In practice most are "C++ on POSIX" or "C++ on Windows" implementations and declare lots of names that are not in the C++ standard.
The namespace pollution problem is well known (11196, 51749 and others), with no simple solution.
The problem is that most C++ standard library implementations don't control the C library and just include the platform's native C headers, which pull in other names.
In the above example, can I resolve the problem without renaming my clone() functions (or the anonymous namespace) but still including ?
In your specific case you can solve the name lookup problem by putting your clone overload in the global namespace so lookup finds it at the same time as the function in <sched.h> and by making it static to give it internal linkage again.
yes, because ::clone looks for clone first in the global (outermost) namespace, and then in the anonymous namespace.
Nothing prevents you (or library providers) to pollute any namespace (global included) but 'std' which is reserved for the standard.
Naming the anonymous namespace could be a way out.
If the question #2 is "Does the standard allow the pollution of global namespace by including a standard header, i.e. making available more symbols than the standard require?". Then I guess the answer is yes, otherwise the constraint imposed on standard library vendors could be too stringent.
Implementation is allowed to put definitions into the global namespace in some cases.
First, a C++ library header is allowed to include other C++ headers:
N3337 17.6.5.2 Headers [res.on.headers] P1:
A C++ header may include other C++ headers. A C++ header shall provide the declarations and definitions
that appear in its synopsis. A C++ header shown in its synopsis as including other C++ headers shall provide
the declarations and definitions that appear in the synopses of those other headers.
The included C++ header can be a wrapper for a C library. Names of these C++ headers start with c, like <cstdlib>.
These headers are allowed to put corresponding C-library definitions in the global namespace first, and then inject them into std namespace.
17.6.1.2 Headers [headers] P4:
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).
Thus, the functions defined in the C standard library can end up in the global namespace.
The clone function, however, in not part of C standard library (it is part of POSIX standard) and thus not formally allowed to appear in the global namespace by the C++ standard.
I understand that rand(), as an example function from <cstdlib>, exists both in the global and the std namespace.
In effect the following will compile without errors, i.e. both calls to std::rand() and rand() will be legit.
#include <cstdlib>
int main() {
std::rand();
rand();
}
What is the use for this and how exactly is it implemented (the function being in both namespaces)?
The behavior is Uspecified behavior as per standard.
As per the standard including cstdlib imports the symbol names in std namespace and possibly in Global namespace. If you rely on symbol names being included in global namespace then your program is non portable and you are relying on behavior of a specific implementation.
To not rely on the implementatio behavior you must:
Include cstdlib and use fully qualified name for rand.
std::rand()
References:
C++11 Standard: D.5 C standard library headers
Para 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. —end example ]
Good Read:
Should I include <xxxx.h> or <cxxxx> in C++ programs?
The reason is that it's originally a C function. It comes from C.
C++ re-implemented C functions like these into a std namespace. There is no difference that I know of, but it is recommended that C++ programmers use the function in the std:: namespace, first including the "c"whatever header (which is what you have indeed done with the "cstdlib" header).
(Plain C programmers would include the "stdlib.h" header, by the way.)
In C++11 I can choose whether I want to use the types defined in with or without the namespace std::
At least my compiler (g++ 4.7) accepts both variants.
My question is: What is the recommended way to use the typedefs from cstdint. With or without the namespace? What are the advantages or disadvantages? Or is it only a matter of style?
so variant a):
#include <cstdint>
std::uint8_t n = 21;
resp:
#include <cstdint>
using std::uint8_t;
uint8_t n = 21;
or variant b):
#include <cstdint>
uint8_t n = 21;
Prefer names declared in the std namespace. The reason is given in §17.6.1.3/4 (ISO/IEC 14882:2011(E), C++11):
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).
If you use the names from the <cname> headers without std, your program is relying on unspecified requirements.
This was different in C++03 and earlier where names were only supposed to appear in the std namespace. However, the reality was that many implementations were simply injecting the contents of the C standard library headers <name.h> into std and so this was accommodated for in C++11. The corresponding section (§17.4.1.2/4) from the C++03 standard says:
Except as noted in clauses 18 through 27, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in ISO/IEC 9899:1990 Programming Languages C (Clause 7), or ISO/IEC:1990 Programming Languages—C AMENDMENT 1: C Integrity, (Clause 7), as appropriate, as if by inclusion. In the C++ Standard Library, however, the declarations and definitions (except for names which are defined as macros in C) are within namespace scope (3.3.5) of the namespace std.
Further to this, qualifying names with std:: helps to avoid collisions - you know exactly what you're getting if you fully qualify it. If you're really going to do using namespace std or using std::something, at least do it in as minimal a scope as you can.
In C++11, for the C headers that are explicitly named in the C++ standard, the following holds:
An implementation is required for the <foo.h> versions to add them in the global namespace, and allowed to add them to the std:: namespace.
An implementation is required for the <cfoo> versions to add them in the std:: namespace, and allowed to add them to the global namespace.
The reason for wrapping things in the std namespace in the <cstdint> header is to avoid name collisions, which are quite unpleasant when they happen. However, in this case, it is very unlikely that the types will be found somewhere else. So I would use <stdint.h>, especially because this feature was introduced in C before it was added to C++, and hence the <stdint.h> header is older than <cstdint>, and therefore available in older compilers.
If you have decided that you want these names in the global namespace, you should also prefer <stdint.h> to <cstdint> followed by using namespace std, as the latter will dump all the other std stuff from other <cfoo> headers yhou have included into the global namspace too, which you probably do not want, as many other standard names are much more collision-prone than the likes of uint8_t.
Include <cstdint> and use std:: or include <stdint.h> to use unqualified type names. There are some platforms (e.g. QNX SDP 6.6) on which <cstdint> doesn't declare those types in the global namespace.
My personal style is to always fully qualify names so it is clear where they come from. That is, I would use std::uint8_t. That is, I would include <cstdint> and use qualified names.
That said, note that use of std::uint8_t is only indicated if you really mean to use a type with exactly 8 bits. If the platform you are running your code on doesn't have such a type, e.g., because it uses 9 bit units as its basic entity, the program is supposed not to compile. If you want to use the smallest unsigned with 8 bits available, you want to use uint_least8_t.
What is the namespace for math functions? Global or std?
Consider cos function. It has 3 overloads. But there is also legacy cos from math.h. C doesn't know anything about function overloading. Therefore cos(x) can't be resolved to cos(float). The solution is to call the single precision version explicitly cosf(x). Did I miss anything?
You get the same functions by including <math.c> and <cmath> in C++, the only differences is the namespace. I.E. including <math.h> also gives you the overload.
In theory, in C++03, using <math.h> gives you the symbols defined in the global namespace and also in the std namespace while using <cmath> gives you the symbols defined in the std namespace and not in the global namespace.
The practice is different and C++ 0X aligned the theory with the practice. <math.h> gives you the symbols defined in the global namespace and perhaps also in the std namespace while using <cmath> gives you the symbols defined in the std namespace and perhaps also in the global namespace.
They are in the std namespace. But, for backwards compatibility reasons the cmath header also shows them in the global namespace with a using std::cos;.
The cXXX headers place all their stuff in the std namespace. They may also put them in the global namespace but it's not required.
This is from C++0x, the upcoming standard, section D.7:
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. —end example ]
This is unchanged from section D.5 from C++03 (it's made more explicit in the newer standard but the effect is the same):
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 also placed within the namespace scope of the namespace std and is followed by an explicit using-declaration.
3/ [Example: The header <cstdlib> provides its declarations and definitions within the namespace std. The header <stdlib.h> makes these available also in the global namespace, much as in the C Standard. —end example]
If you include the 'old-style' XXX.h header, it's placed in both namespaces (in both iterations of the standard).
If you are using C++ you can rely on the function overloading.
There are three version of cos:
double cos ( double x );
float cos ( float x );
long double cos ( long double x );
But if you are using only C or you want portabilty only the double version of this function exists with this name. The float function is cosf.