Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does "using namespace" do exactly?

Tags:

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.
like image 765
marcv81 Avatar asked Dec 07 '15 08:12

marcv81


People also ask

What is the benefits of using namespace?

The biggest advantage of using namespace is that the class names which are declared in one namespace will not clash with the same class names declared in another namespace. It is also referred as named group of classes having common features.

Is it good practice to use namespace?

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.

What is the advantage of using namespace in C++?

Namespace in C++ is the declarative part where the scope of identifiers like functions, the name of types, classes, variables, etc., are declared. The code generally has multiple libraries, and the namespace helps in avoiding the ambiguity that may occur when two identifiers have the same name.

What is the function of using namespace std in C++?

In C++, a namespace is a collection of related names or identifiers (functions, class, variables) which helps to separate these identifiers from similar identifiers in other namespaces or the global namespace. The identifiers of the C++ standard library are defined in a namespace called std .


2 Answers

The directive using namespace X; makes names from namespace X visible inside the namespace containing the directive. That is, when looking up a name n 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:

std::string test = "Test";

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:

namespace X
{
  struct C
  {
    static std::string test;
  };
}

using namespace X;
std::string C::test = "Test";

In this code, the compiler needs to know what C is to make sense of the definition of C::test. It therefore does a name lookup of C, which indeed finds X::C thanks to the using directive.

like image 152
Angew is no longer proud of SO Avatar answered Sep 23 '22 01:09

Angew is no longer proud of SO


using namespace means you use definitions from the namespace you specified, but it doesn't mean that everything that you define is being defined in a namespace you use.

Logic of this behavior is pretty simple. Let's say we have the following example:

namespace X
{
    extern string test;
};

namespace Y
{
    extern string test;
};

using namespace X;
using namespace Y;

string test = "value";

Following your example logic, compiler just would not know in which namespace it should define test, so you would have to declare the namespace explicitly. In a real life it is defined in a global namespace.

In your specific case you define the test variable outside of the X namespace where it is declared as extern. Linker looks for definition of the X::test but doesn't find and as a result you see this error.

like image 23
Alex Avatar answered Sep 26 '22 01:09

Alex