Can somebody please explain the following:
$ cat test.cpp
#include <string>
std::string div;
$ g++ -c test.cpp
$ g++ -std=c++11 -c test.cpp
test.cpp:2:13: error: 'std::string div' redeclared as different kind of symbol
In file included from /usr/include/c++/4.7.1/cstdlib:66:0,
from /usr/include/c++/4.7.1/ext/string_conversions.h:37,
from /usr/include/c++/4.7.1/bits/basic_string.h:2814,
from /usr/include/c++/4.7.1/string:54,
from test.cpp:1:
/usr/include/stdlib.h:787:14: error: previous declaration of 'div_t div(int, int)'
$
Shouldn't the div
symbol be in std
namespace also for C++11 mode? Or is it something specific to my system?
Avoiding Name Collisions NET Framework namespaces address a problem sometimes called namespace pollution, in which the developer of a class library is hampered by the use of similar names in another library. These conflicts with existing components are sometimes called name collisions.
An unnecessary distinctive syntax: All other languages with namespaces just use '. ' as separator as its not ambiguous with other uses of '. '. And, more critically, c++ never introduced a scoped using directive.
The statement using namespace std is generally considered bad practice. The alternative to this statement is to specify the namespace to which the identifier belongs using the scope operator(::) each time we declare a type.
Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries.
/usr/include/stdlib.h
Every name in a .h
C stdlib header resides in the global namespace (obviously).
Additionally, any cHEADER
C++ stdlib header will define the corresponding names from HEADER.h
in the std
namespace, but is also allowed to have them in the global namespace (so they can just do
// cHEADER
#include <HEADER.h>
namespace std{
using ::one_name_from_HEADER;
using ::another_name_from_HEADER;
// and so on...
}
and be done with it).
§D.5 [depr.c.headers]
p2 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 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 namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).p3 [ 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 ]
As you can see, the same is also true the other way around (<HEADER.h>
may introduces names to the std
namespace, as if
// HEADER.h
#include <cHEADER>
using std::one_name_from_HEADER;
using std::another_name_from_HEADER;
// and so on...
}
), which makes the whole distinction between those headers rather... useless, really.
div
is a function from <stdlib.h>
.
In C++11, the <c
blah>
headers were allowed to place stuff in the global namespace.
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 namespace std by explicit using-declarations (7.3.3).”
Reflecting the reality of common C++ implementations.
So nothing changed, really, except the formal: that the behavior you see is now sanctioned by the standard instead of being an implementation artifact that one had to make allowance for.
Also, the formal change makes it easier to argue on SO that one should better include .h
headers rather than c
xxx headers…
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With