Does the runtime library pollute the global namespace?
I don't think you really understand the terms you are using, but the names in the C++ Standard Library exist in the std namespace, so the answer is no. The names in the header files that originated in the C Standard Library are placed in the global namespace, if you #include them via the .h filenames, such as:
#include <stdio.h>
if you #include them like this:
#include <cstdio>
then the names exist in both global and std namespaces.
The reason for placing objects in the std namespace is not so much to avoid "namespace polution", which is hardly a value neutral term, but to avoid name clashes.
The runtime library is required to use reserved identifiers. Without namespace qualification, these must begin with two underscores: __start, etc.
You are not allowed to use reserved names. The library is not allowed to use your names. If either crosses over to the other, it is "pollution" which is illegal.
Essentially, the situation is the same for C and C++ except, as the other answers point out, in C++ most standard library names have namespace qualification.
Most of the library cleanly goes in namespace std: -- however, for backwards compatibility with C, you may choose to "pollute" the global namespace by including old headers like <math.h> (which puts lots of names in the global namespace) instead of the proper new ones like <cmath> (which uses the std: namespace properly).
Related
I'm reading codes that designed an OCR model for chemistry. And I see some lines like this
#include <math.h> // fabs(double)
Is it possible to import just one function like what Python does (from module import function)?
I read the code of cmath. When I do #include <cmath>, the inner codes already do #include <math.h> , thus importing all the functions to the global namespace. What should I do?
With most C++ standard library headers, if you don't do using namespace std; they do not pollute the global namespace and put everything into the namespace std instead. So as long as you don't do using namespace std; there will be no pollution.
<math.h>
is a bit different in that regard. It is one of the standard library headers inherited by C++ from C and therefore it doesn't follow the namespace rules of the C++ standard library. C doesn't have namespaces at all and so including the header will put all its names in the global namespace. There is no way to avoid this. Selective inclusion from headers is not possible in C and C++.
There is an alternative form of the same header:
#include <cmath>
This header will put all the standard library functions into the std namespace as for typical C++ standard library headers.
Unfortunately, the C++ standard does allow compilers/standard library implementations to also put the names in the global namespace when <cmath> is included. So even if you use this variant, you have no guarantee that it won't pollute the global namespace and I think indeed most implementations do.
Unfortunately you have to live with C standard library functions which were inherited into C++ polluting the global namespace. I don't think there is anything that can be done about it.
What you can do is put all of your own program's declarations into a namespace, e.g.:
namespace my_stuff {
// ...
}
If there is a name conflict, then in most situations your own one will be chosen over the global one as long as you are staying in the namespace.
I had a quick question. Is there a way to force the standard namespace to have the std:: scope qualifier? Something like abs and what not; all std functions have to have their scope defined.
I'm not using namespace std anywhere nor am I using std::abs or something like that. It might be important to say I have Windows.h included, which I feel may be where some of these unscoped functions are originating from.
The standard does not forbid other namespaces to have functions that are named abs just because there are functions named abs in std namespace. That's true of all other functions defined in the std namespace.
If you want to be certain that you use std::abs. and not any other version of abs, then by all means, use std::abs. Then, it's immaterial whether there are other versions of abs defined in the windows.h header file.
Calling abs instead of std::abs you are simply using abs from C
The rule in C++ is that #include <cmath> puts the declaration of abs in the namespace std and is allowed to also put the declaration of abs in the global namespace.
Another rule in C++ is that #include <math.h> puts the declaration of abs int he global namespace and is allowed to also put the declaration of abs in the namespace std.
So, no, you can't assume that #include <cmath> won't put abs into the global namespace.
The reason for this rule instead of the "obvious" one that #include <cmath> puts names only in std is that the latter rule can be nasty to implement if the C++ implementors don't also have control over the C headers. In that case, the C++ headers would have to have duplicate declarations for all of the C functions, and any change to the C headers would have to be carried through into the C++ headers, which produces a logistical nightmare.
From what I understand, one of the reasons the C++ versions of C libraries like stdlib.h (cstdlib) were introduced was so that the global namespace is not polluted.
But it turns out that I am able to use malloc in the global namespace even though I did not #include <stdlib.h>.
So then why should I #include <cstdlib> and then use std::malloc?
(I'm using g++ version 4.8.2)
There used to be a requirement that the C headers (*.h) only put names into the global namespace and that the corresponding C++ headers only put names into std. That turned out to be impractical, and was often not followed. So the standards committee standardized existing practice, and changed the rule so that the C headers must put names into the global namespace and may put them into std, and that the C++ headers must put names into std and may put them into the global namespace.
The reason that the old rule was impractical is simply that it would require duplicating all of the C header content inside namespace std, with a corresponding burden in maintenance of having two sets of code to update. Add to that the fact that in some cases the C headers are handled by a completely separate development team. The cost of this approach is prohibitive.
To answer the final question, either use #include <stdlib.h> and malloc or use #include <cstdlib> and std::malloc.
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.)
What is the difference between stdint.h and cstdint?
Both of them are available in MSVC (Visual Studio 2010) and gcc-4.5.1. Also both define the intX_t/uintX_t types (where X is the size in bytes of the type).
If the rationale in both headers is the same (portable types), what decisions I must take to decide on one or the other?
The stdint.h defines each type without any namespace, the cstdint types lies in the std namespace.
Is there any reason to include or to not include the defined types into the std namespace? What is different between the two headers?
cstdint has no file extension and uses the c prefix, stdint.h uses the .h extension.
What are the naming conventions for this headers? the c prefix indicates that this is a C library? there's a reason for the lack of file extension in cstdint?
The original intention in C++98 was that you should use <cstdint> in C++, to avoid polluting the global namespace (well, not <cstdint> in particular, that's only added in C++11, but the <c*> headers in general).
However, implementations persisted in putting the symbols into the global namespace anyway, and C++11 ratified this practice[*]. So, you basically have three options:
Use <cstdint> and either fully qualify each integer type you use or else bring it into scope with using std::int32_t; etc (annoying because verbose, but it's the right way to do it just like for any other symbol in the C++ standard library)
Use <stdint.h> (slightly bad because deprecated)
Use <cstdint> and assume your implementation will put the symbols in the global namespace (very bad because not guaranteed).
In practice I suspect that an annoying large amount of code uses the last option, simply because it's easy to do by accident on an implementation where <cstdint> puts the symbols in the global namespace. You should try to use the first. The second has one virtue, that it is guaranteed to put stuff in the global namespace instead of only maybe doing it. I don't think that's particularly useful, but it might save some typing if that's your priority.
There's a fourth option, #include <cstdint> followed by using namespace std; which is sometimes useful but there are places that you shouldn't put the using namespace std;. Different people will have different ideas where those places are, but "at top level in a header file" is worse than "at top level in a cpp file", which is worse than "in a limited scope". Some people never write using namespace std; at all.
[*] That means C++ standard headers are permitted to put stuff in the global namespace but not required to. So you have to avoid colliding with those symbols, but you can't actually use them because they might not be there. Basically, the global namespace in C++ is a minefield, try to avoid it. One might argue that the committee has ratified a practice by implementations that is nearly as harmful as sticking using namespace std; at top level in a header file -- the difference being that the implementations only do it for symbols in the C standard library, whereas using namespace std; does it for C++-only symbols too. There's a section in the C standard that lists names reserved for future additions to the standard. It's not a completely stupid idea to treat those names as reserved in the C++ global namespace too, but it's not essential.
Including cstdint imports the symbol names in std namespace and possibly in Global namespace.
Including stdint.h imports the symbol names in Global namespace and possibly in std namespace.
Features of C standard Library are also provided in the C++ Standard library and as a general naming convention they are pre-pended by an c to the corresponding names in C standard library.
In C++, You should be using:
#include <cstdint>
and fully qualify the symbol names you use with std::
while in C, You should use:
#include <stdint.h>
Annex D (normative) Compatibility features [depr] states:
D.6 C standard library headers
1 For compatibility with the C standard library and the C Unicode TR, the C++ standard library provides the 25 C headers, as shown in Table 151.
Which include:
<assert.h> <float.h> <math.h> <stddef.h> <tgmath.h>
<complex.h> <inttypes.h> <setjmp.h> <stdio.h> <time.h>
<ctype.h> <iso646.h> <signal.h> <stdint.h> <uchar.h>
<errno.h> <limits.h> <stdarg.h> <stdlib.h> <wchar.h>
<fenv.h> <locale.h> <stdbool.h> <string.h> <wctype.h>
And further,
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 ]
cstdint is C++11 header, stdint.h is C99 header (C and C++ are different languages!)
MSVC 2008 contains neither stdint.h nor cstdint.
Implementations of cstdint are mostly simply #include <stdint.h> with some namespace/language fixes.