Namespaces don’t really fit into the functions category, but they are an important concept that we need to cover before we get to classes and object oriented programming, and this is really as good a place as any.
Pretend you are the teacher of a classroom of students. For sake of example, let’s say there are two boys named “Alex”. If you were to say, “Alex got an A on his test”, which Alex are you referring to? Nobody knows, unless you have a way to disambiguate which Alex you mean. Perhaps you point at one, or use their last names. If the two Alex’s were in different classrooms, there wouldn’t be a problem — the problem is really that there are two things with the same name in the same place. And in fact, as the number of students in the classroom increase, the odds of having two students with the same first name increases exponentially.
A similar issue can arise in programming when two identifiers (variable and/or function names) with the same name are introduced into the same scope. When this happens, a naming collision will result, and the compiler will produce an error because it does not have enough information to resolve the ambiguity. As programs get larger and larger, the number of identifiers increases linearly, which in turn causes the probability of naming collisions to increase exponentially.
Let’s take a look at an example of a naming collision. In the following example, foo.h and goo.h are the header files that contain functions that do different things but have the same name and parameters.
foo.h:
// This DoSomething() adds it's parameters
int DoSomething(int nX, int nY)
{
return nX + nY;
}
goo.h:
// This DoSomething() subtracts it's parameters
int DoSomething(int nX, int nY)
{
return nX - nY;
}
main.cpp:
#include <foo.h>
#include <goo.h>
#include <iostream>
int main()
{
using namespace std;
cout << DoSomething(4, 3); // which DoSomething will we get?
return 0;
}
If foo.h and goo.h are compiled separately, they will each compile without incident. However, by including them in the same program, we have now introduced two different functions with the same name and parameters into the program, which causes a naming collision. As a result, the compiler will issue an error:
c:\\VCProjects\\goo.h(4) : error C2084: function 'int __cdecl DoSomething(int,int)' already has a body
In order to help address this type of problem, the concept of namespaces was introduced.
What is a namespace?
A namespace defines an area of code in which all identifiers are guaranteed to be unique. By default, all variables and functions are defined in the global namespace. For example, take a look at the following snippet:
int nX = 5;
int foo(int nX)
{
return -nX;
}
Both nX and foo() are defined in the global namespace.
In the example program above that had the naming collision, when main() #included both foo.h and goo.h, the compiler tried to put both versions of DoSomething() into the global namespace, which is why the naming collision resulted.
In order to help avoid issues where two independent pieces of code have naming collisions with each other when used together, C++ allows us to declare our own namespaces via the namespace keyword. Anything declared inside a user-defined namespace belongs to that namespace, not the global namespace.
Here is an example of the headers in the first example rewritten using namespaces:
foo.h:
namespace Foo
{
// This DoSomething() belongs to namespace Foo
int DoSomething(int nX, int nY)
{
return nX + nY;
}
}
goo.h:
namespace Goo
{
// This DoSomething() belongs to namespace Goo
int DoSomething(int nX, int nY)
{
return nX - nY;
}
}
Now the DoSomething() inside of foo.h is inside the Foo namespace, and the DoSomething() inside of goo.h is inside the Goo namespace. Let’s see what happens when we recompile main.cpp:
int main()
{
using namespace std;
cout << DoSomething(4, 3) << endl; // which DoSomething will we get?
return 0;
}
The answer is that we now get another error!
C:\\VCProjects\\Test.cpp(15) : error C2065: 'DoSomething' : undeclared identifier
What happened is that when we tried to call the DoSomething() function, the compiler looked in the global namespace to see if it could find a definition of DoSomething(). However, because neither of our DoSomething() functions live in the global namespace any more, it failed to find a definition at all!
There are two different ways to tell the compiler which version of DoSomething to use.
The scope resolution operator (::)
The first way to tell the compiler to look in a particular namespace for an identifier is to use the scope resolution operator (::). This operator allows you to prefix an identifier name with the namespace you wish to use.
Here is an example of using the scope resolution operator to tell the compiler that we explicitly want to use the version of DoSomething that lives in the Foo namespace:
int main(void)
{
using namespace std;
cout << Foo::DoSomething(4, 3) << endl;
return 0;
}
This produces the result:
7
If we wanted to use the version of DoSomething() that lives in Goo instead:
int main(void)
{
using namespace std;
cout << Goo::DoSomething(4, 3) << endl;
return 0;
}
This produces the result:
1
The scope resolution operator is very nice because it allows us to specifically pick which namespace we want to look in. It even allows us to do the following:
int main(void)
{
using namespace std;
cout << Foo::DoSomething(4, 3) << endl;
cout << Goo::DoSomething(4, 3) << endl;
return 0;
}
This produces the result:
7 1
It is also possible to use the scope resolution operator without any namespace (eg. ::DoSomething). In that case, it refers to the global namespace.
The using keyword
The second way to tell the compiler to look in a particular namespace for an identifier is to use the using keyword. The using keyword tells the compiler that if it can not find the definition for an identifier, it should look in a particular namespace to see if it exists there. For example:
int main(void)
{
using namespace std;
using namespace Foo; // look in namespace Foo
cout << DoSomething(4, 3) << endl;
return 0;
}
The using namespace Foo line causes DoSomething(4, 3) to resolve to Foo::DoSomething(4, 3). Consequently, this program prints:
7
Similarly, the following example:
int main(void)
{
using namespace std;
using namespace Goo; // look in namespace Goo
cout << DoSomething(4, 3) << endl;
return 0;
}
causes DoSomething(4, 3) to resolve to Goo::DoSomething(4, 3). Consequently, this program prints:
1
One more example:
int main(void)
{
using namespace std;
using namespace Foo; // look in namespace Foo
using namespace Goo; // look in namespace Goo
cout << DoSomething(4, 3) << endl;
return 0;
}
As you might have guessed, this causes an error:
C:\\VCProjects\\Test.cpp(15) : error C2668: 'DoSomething' : ambiguous call to overloaded function
In this case, it couldn’t find DoSomething() in the global namespace, so it looked in both the Foo namespace and the Goo namespace (and the std namespace). Since DoSomething() was found in more than one namespace, the compiler couldn’t figure out which one to use.
The using keyword is scoped just like a normal variable — if it is declared inside a function, it is only in effect during that function. If it is declared outside of a function, it affects the whole file from that point forward. The using keyword can save a lot of typing when you have code that needs to use many identifiers from a particular namespace… like when you’re doing input and output!
Consider the following example:
int main()
{
using namespace std;
cout << "Enter a number: ";
int nX;
cin >> nX;
cout << "You entered " << nX << endl;
return 0;
}
Because of the using namespace std line, this function is identical to the following:
int main()
{
std::cout << "Enter a number: ";
int nX;
std::cin >> nX;
std::cout << "You entered " << nX << std::endl;
return 0;
}
However, the top example is generally considered easier to read!
Using the using keyword judiciously can make your code neater and easier to read. Although the using keyword can be used outside of a function to help resolve every identifier in the file, this is not recommended, as it increase the chance of identifiers from multiple namespaces conflicting, which somewhat defeats the point of namespaces in the first place.
7.12 — Handling errors (assert, cerr, exit, and exceptions)
|
Index
|
7.10 — Recursion
|
7.12 — Handling errors (assert, cerr, exit, and exceptions)
Index
7.10 — Recursion
“In order to help address this type of problem, the concept of namespaces was introduced.”
“In this case, it couldn’t find DoSomething() in the global namespace, so it looked in both the Foo namespace and the Goo… ”
Vertical scrollbar above these lines are not visible.So not able to read the content.
Renu
I put in a workaround to address the issue. Non-IE browsers render their scrollbars on the outside of the element needing to be scrolled, but IE (stupidly) renders them on the inside, which obliterates the element being viewed when it’s only one line high.
I put in some conditional CSS to force IE to render additional space at the bottom of all PRE elements. That way, if it decides to render scrollbars on the inside of the element, there’s enough room to do so without visually overriding the text. As a side effect, all non-scrolled PRE elements will have extra room at the bottom when viewed in IE, but that side effect is minor.
Firefox users aren’t affected by this.
What if we want to use Foo namespace first and then Goo namespace? Is it possible to discontinue using a namespace and start using another?
You can always reference a namespace directly using the scope resolution operator (::).
However, if you want to use the using statement, I think the only way to do this would be to put the using statement inside it’s own block, along with the relevant code.
Something like this:
int main() { { using namespace foo; // calls to foo:: stuff here } // using namespace foo expires { using namespace goo; // calls to goo:: stuff here } // using namespace goo expires }Thanks.
this is useful, i suggest to add this example to above lesson.
great tutorial!
I agree; it should be in the above examples as it’s not explained earlier. Other than this, I really enjoy your tutorials!
Thank you Alex!
–
You have put “In the following example, fool.h and goo.h are the header files” when the headers are “foo.h” and “goo.h”.
[ Thanks! Fixed. -Alex ]
Another very well-written section.
One very small typo: “the compiler tried to put both versions” or maybe “the compiler tries to put both versions”
[ Thanks! -Alex ]
The link to the next lesson at the top should point to section 7.12, not to 8.1.
Great tutorial by the way. Thanks for all the effort.
[...] 2007 Prev/Next Posts « 7.9 — The stack and the heap | Home | 7.11 — Namespaces » Monday, August 13th, 2007 at 9:30 [...]
[...] No, thank you! -Alex ] 4 Learn C++ – » 7.11 — Namespaces says: April 28th, 2008 at 9:06 pm [...] 7.12 — Handling errors (assert, cerr, [...]
Just to remaind you guys, all header files(*.h) are just declaration of
structs, classes, parameters, functions prototypes specifying the interface for the
operations
What about ‘namespace pollution’? You should never ‘use’ a namespace in a header file.
Ok well maybe someone can answer this for me – I kow this has to be the easiest code in the world but after trying to complete it for what? going on 12 hours now, I guess i just suck!(lol).
This is what I have to do and I can do all of it but figuI just ca’t seem to get the enumeration type used in conjunction with the menu. This is like really becoming quite annoying now.So if anybody would be wil;ling to help me with this one part, I would be so grateful.
The user interface should allow the entry of two integers and the selection of a mathematical operation from a displayed menu. The output of the calculator program should look similar to:
Result: 5 X 6 = 30
The calculator should be able to perform addition, subtraction, division, multiplication, and modulus division. The program must include appropriate variables, an enumeration type that is used in conjunction with the menu, and a switch structure.
Why can’t I define a function outside a namespace once it has been declare in? For example the code:
#include using namespace std; namespace mio{ int suma(int, int); } using namespace mio; int suma(int a, int b) { return a+b; } void main() { cout << "nLa suma es: " << suma(5,9) << endl; }will issue the next error: Ambiguity between ‘mio::suma(int,int)’ and ‘suma(int,int)’ in function main().
question
is “int main(void)” and “int main()” the same thing?
yes!
In this function, the number of arguments is zero
but in
The number of arguments is not know[infinity].
How to get the out put in GUI for C++ Programing?
my question
well.. this didn’t seem like the hardest section (pointers was a hard concept for someone new to cpp), yet for some reason I cant get this to work!
I’m also confused that you mention the header files, but then the functions that you use in the header files don’t look like simple prototypes, since they have a return statements, they look like full functions ..hmm
The simplified example is below:
header.h:
#ifndef …etc
namespace exF{ bool bX() }externalFn.cpp:
bool bX(){ return true;}so in my main.cpp, I should just be able to use:
main.cpp :
#include "header.h" int main(){ if (exF:bX() == true){ cout << "yay"; } retrun 0; }but the only error I get is: undefined reference to ‘exf::bx()’
I dont understand why, should we actually be defining the full functions (not just the proto) in the header files now?
(The rest of this tutorial has been great by the way… Thank you so much for sharing your wealth of knowledge and teaching skills ;) )
I’m not certain why, but removing the inline option (learnt in the previous lesson) solved my problem.
nice work!!
I’m confused! Consider “cin”, for example. It is in the namespace std. Is there any other namespaces with object “cin”? Otherwise, why we need to declare the namespace std::cin.
In other words, would you please give me an example for two standard objects with the same name in different namespaces? (I mean an object that is not defined by user)
He used the ‘std::cin’ as an example to show you how it works.
also, while I’m not aware of such colliding cases, it might be possible that custom namespaces have colliding names, and this is when it might come useful.
Fantastic tutorial, I’m really enjoying it – thank you very much for sharing your knowledge, Alex. At this point of tutorial, I have a question:
I followed the examples in this section, and found out everything works fine when using scope resolution operator:
double dSin = 0.0;
double dCos = 0.0;
foo::GetSinCos(30.0, dSin, dCos);
cout << "The sin is " << dSin << endl;
cout << "The cos is " << dCos << endl;
But when I try the "using namespace" keyword method, I get "ambiguous call to overloaded function" error:
double dSin = 0.0;
double dCos = 0.0;
using namespace foo;
GetSinCos(30.0, dSin, dCos);
cout << "The sin is " << dSin << endl;
cout << "The cos is " << dCos << endl;
Does anyone have an idea why is this happening? Thanks :)
This tutorial is really very helpful.Thanks Alex.
one comment on the header files included in the main.cpp
User defined header files should be in double quotes(ex: #include “a.h”) otherwise compiler will throw an error.