Search

Enter your search terms

Submit search form

1.8a — Naming conflicts and the std namespace

By Alex on November 6th, 2016 | last modified by Alex on March 20th, 2017

Let’s say you are driving to a friend’s house for the first time, and the address given to you is 245 Front Street in Mill City. Upon reaching Mill City, you pull up your map, only to discover that Mill City actually has two different Front Streets across town from each other! Which one would you go to? Unless there were some additional clue to help you decide (e.g. you remember his house is near a particular donut shop) you’d have to call your friend and ask for more information. Because this would be confusing and inefficient (particularly for your mailman), in most countries, all street names and house addresses within a city are required to be unique.

Similarly, C++ requires that all identifiers (variable and/or function names) be non-ambiguous. If two identifiers are introduced into the same program in a way that the compiler can’t tell them apart, the compiler or linker will produce an error. This error is generally referred to as a naming collision (or naming conflict).

An example of a naming collision

a.cpp:

1

2

3

4

5

6

#include <iostream>

voiddoSomething(intx)

{

std::cout<<x;

}

b.cpp:

1

2

3

4

5

6

#include <iostream>

voiddoSomething(intx)

{

std::cout<<x*2;

}

main.cpp:

1

2

3

4

5

6

7

8

voiddoSomething(intx);// forward declaration for doSomething

intmain()

{

doSomething(5);

return0;

}

Files a.cpp, b.cpp, and main.cpp will all compile just fine, since individually there’s no problem. However, when a.cpp and b.cpp are put in the same project together, a naming conflict will occur, since the function doSomething() is defined in both. This will cause a linker error.

Most naming collisions occur in two cases:
1) Two files are added into the same project that have a function (or global variable) with the same name (linker error).
2) A code file includes a header file that contains an identifier that conflicts with something else (compile error). We’ll discuss header files in the next lesson.

As programs get larger and use more identifiers, the odds of a naming collision being introduced increases significantly. The good news is that C++ provides plenty of mechanisms for avoiding naming collisions (such as local scope, which keeps variables inside functions from conflicting with each other, and namespaces, which we’ll introduce shortly), so most of the time you won’t need to worry about this.

The std namespace

When C++ was originally designed, all of the identifiers in the C++ standard library (such as cin and cout) were available to be used directly. However, this meant that any identifier in the standard library could potentially conflict with a name you picked for your own identifiers. Code that was working might suddenly have a naming conflict when you #included a new file from the standard library. Or worse, programs that would compile under one version of C++ might not compile under a future version of C++, as new functionality introduced into the standard library could conflict. So C++ moved all of the functionality in the standard library into a special area called a namespace.

Much like a city guarantees that all roads within the city have unique names, a namespace guarantees that identifiers within the namespace are unique. This prevents the identifiers in a namespace from conflicting with other identifiers.

It turns out that std::cout’s name isn’t really “std::cout”. It’s actually just “cout”, and “std” is the name of the namespace it lives inside. All of the functionality in the C++ standard library is defined inside a namespace named std (short for standard). In this way, we don’t have to worry about the functionality of the standard library having a naming conflict with our own identifiers.

We’ll talk more about namespaces in a future lesson and also teach you how to create your own. For now, the only thing you really need to know about namespaces is that whenever we use an identifier (like std::cout) that is part of the standard library, we need to tell the compiler that that identifier lives inside the std namespace.

Rule: When you use an identifier in a namespace, you always have to identify the namespace along with the identifier

Explicit namespace qualifier std::

The most straightforward way to tell the compiler that cout lives in the std namespace is by using the “std::” prefix. For example:

1

std::cout<<"Hello world!";

This is the safest way to use cout, because there’s no ambiguity about where cout lives (it’s clearly in the std namespace).

C++ provides other shortcuts for indicating what namespace an identifier is part of (via using statements). We cover those in lesson 4.3c -- Using statements.

Many books use it because it's easier to show code "snippets". Typing "using namespace std" is just referring (use namespaces from the standard library, hence std::).
It's not best practice to use "using namespace std", why?

Example if you are using two libraries:

using namespace example;
using namespace example1;

and in both libraries, you have "cout", there will be conflict. Because compiler can't decide which to use!
If you wrote it like this:

example::cout or example1::cout, this will work because you have used "cout" from separate libraries.
-----------------------------------------------------------------------------------------------------------

Still if you want to use "using namespace std",
you can do it this way:

My dear c++ Teacher,
Please let me explain you that section 4.1a deals with naming confliction between variables. My question is about naming confliction between function and variable. My view is following:
1. From 1st program follows that:
1a. Compiler permits same name for function and variable inside its body.
1b. When in function's body (in this case main()) there is function call before variable's definition, latter's name can be same as that of called function. My explanation is that called function, after its execution, is destroyed, so its name is available.
2. From 2nd program it follows that when in function's body there is variable's definition before function's call, called function's name can NOT be same as variable's, apparently for variable is not yet destroyed so its name is not available inside hosting function.
I my view correct?
With regards and friendship.

No. A variable name inside a block shadows an identical name from outside the block. So in the second program, the variable x shadows the function x. Therefore, when you try to call x(), the compiler notes that x is a variable, not a function, so calling it like a function doesn't make sense.

In the top program, when the x function is called, the x variable hasn't shadowed it yet, so this is legal.

cout is reserved word right !
but we should explicitly tell to the compiler that it is from std namespace
does that mean we should create other identifiers namely cout cin but from other user-defined namespaces ?

My dear c++ Teacher,
Please let me say under example codes you state "Files a.cpp, b.cpp, and main.cpp will all compile just fine, since individually there’s no problem".
I tried compile them individually by
https://www.tutorialspoint.com/compile_cpp_online.php
for a.cpp and b.cpp files it thrown error:
"undefined reference to `main'"
for main.cpp it thrown error:
"undefined reference to `doSomething(int)'"
With regards and friendship.

Because the functionality you need is actually defined inside the iostream header (inside a namespace). To use it, you must first include the header (which makes the functionality of that header available for your use) and then tell the compiler how to get to it (inside the std namespace). Both steps are required.

If you could just "use namespace std" and get to everything in the standard namespace, the implication is that you'd essentially be including the entire standard library, which would make your compilations a lot slower. It's better to pull in only what you need.

Hi Alex,
Thanks for your previous reply. How does this piece of code work because surely the variable x is defined twice within the same function and also they share the same local scope. Also the output for "outer block y is re-assigned to 50 but surely local scope must disable this possibility.

They actually don't share the same scope. Inside the inner block, the name "x" refers to inner block x only. This is called shadowing. I talk about scoping and shadowing related topics in a lot more detail in lesson 4.1. Because there is no separate inner block y defined, while inside the inner block, y still refers to the y defined in the outer block.

Hi Alex,
I have outlined function cout() ,in a separate file but still under the same project, as:

1

2

3

4

5

#include <iostream>

intcout()

{

return3+4;

}

Yet for some reason, I have an error stating ambiguity but I have clearly stated the 2 versions of cout (my function and one that lives in the c++ library). I used this example to gain a further understanding of namespaces.

1

2

3

4

5

6

7

8

9

10

11

12

#include <iostream>

usingnamespacestd;

intcout();

intmain()

{

std::cout<<"Thanks for using my service"<<std::endl;

std::cout<<cout()<<std::endl;

return0;

}

Please also note that I have realised the files are compiling and linking well with the expected outputs when I miss out

The problem is this: You have a forward declaration "int cout()", telling the compiler that there is some function (somewhere) named cout. You're also getting a std::cout function from iostream. Because you're "using namespace std;", the compiler can't tell if the call to cout() is supposed to be to "int cout()" or "std::cout". I talk more about using statements in chapter 4. I general, I recommend avoiding them altogether.

Hi Alex,
Great tutorials by the way. Would it be useful to read through this topic and then topic 4.3b- Namespaces straight after since it may give me a better understanding of using and implement namespaces. Or shall I just follow the program and move on to the next module (Header Files). Thank you very much in advance.

The tutorials should teach you everything you need to know in order, so there shouldn't be any problem if you wait until you encounter lesson 4.3b naturally. That said, if you're curious, there's no harm in reading 4.3b ahead of time, though you may encounter some other concepts that haven't been explained yet.

You need to tell the compiler somehow that cout lives in the std namespace. The easiest way to do so is via the std:: prefix. There are other options, such as "using statements", which I cover in chapter 4, but I don't recommend them.

At least in the United States, each block has a range of addresses that all houses on that block fall between. For example, on the first block of the street, all houses might be numbered between 100 and 199, and on the second block, all the houses will be numbered 200 to 299.

That way, even if the street is split into multiple segments (e.g. by a park or river in the middle) or are across town from each other, if you know the address range for a block, you can determine which segment of the street to go to. You'll never get two houses with the same number and street name, because the house numbering for different blocks should never overlap.

Regarding naming collisions or naming conflicts: couldn't we just create names that are practically guaranteed not to ever collide or conflicts, just adding an extra "xy0" to the end of every function we make???

Surely there can be no problem with a "coutxy0()" or "cinz()" or anything similarly named! I plan on using a global namespace directive at the outset and not worrying about collisions afterwards by just creating very unique though simple function names. What could possibly go wrong with such an approach, please?

Alex,
The statement below is real confusing and maybe even misleading. Aren't there other containers in the standard library besides (std namespace)? So, std namesspace is just one(or maybe part of one)of these containers isn't it?

"Everything in the standard library lives inside a special container (called a namespace) that is named std (short for standard)."

Thanks Alex, But it's a bit hard for me to get my mind around exactly what namespaces are, could you give us a better description ?

This is kind of dumb but I'm sure others have wondered about this. I've got another question about std :: cin >> x;. I know this put the user input value of x into memory. But can you put any thing else on that same line of code besides a comment?
Thanks

It's hard to describe namespaces right now because we haven't covered some of the language that I really need to describe them accurately. A way to think of them for now: Namespaces apply a prefix to variable and type names. This prefix functions much like your last name in real life does -- it helps ensure that even though you may have the same first name as someone else, you can still be uniquely identified by using both your names together. Does that make sense? I talk more about namespaces in chapter 4.

As for your second question, because this statement ends in a semicolon, you could put another statement to the right of that statement. However, that's generally considered bad form. One statement per line is the recommended practice, with an optional comment to the right (or above).