The following C++ test code does not link (gcc 4.9.2, binutils 2.25). The error is In function 'main': undefined reference to 'X::test'
.
01: #include <string>
02: #include <iostream>
03:
04: namespace X
05: {
06: extern std::string test;
07: };
08:
09: using namespace X;
10: std::string test = "Test";
11:
12: int main()
13: {
14: std::cout << X::test << std::endl;
15: }
Because of line 09, I was expecting line 10 to define the X::test
variable declared on line 06. I believe that instead an unrelated test
variable is declared and defined in the global namespace, hence the linking error.
Question: Could anyone please explain why my expectation was incorrect, and what is happening exactly?
Not the answer:
- I can make it link changing line 10 to
std::string X::test = "Test";
. - I should not use "using namespace" to begin with.
Best Answer
The directive
using namespace X;
makes names from namespaceX
visible inside the namespace containing the directive. That is, when looking up a namen
in that scope,X::n
can be found. However, it will only be looked for if the compiler needs to look for it.In your example, this declaration:
inside the global namespace makes perfect sense as-is. The name
test
is simply introduced, as with any other declaration. No need to look it up anywhere.This would be an entirely different kettle of fish:
In this code, the compiler needs to know what
C
is to make sense of the definition ofC::test
. It therefore does a name lookup ofC
, which indeed findsX::C
thanks to theusing
directive.