1.8a — Naming conflicts and the std namespace

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




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:

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.

1.9 -- Header files
1.8 -- Programs with multiple files

37 comments to 1.8a — Naming conflicts and the std namespace

  • Anshul

    Does this mean that all functions in standard library are declared inside namespace std?

    • Alex

      Yes. If you use a modern compiler and include the non-.h versions of the headers, all standard library functionality will be inside the std namespace.

      • Anshul

        What is "functionality" in this context? Function declarations or function definitions.

        I am confused. If all the standard library functionality is inside the namespace std which is the part of standard library then what other parts of standard library contain?

        • Alex

          By functionality, I mean the declarations and definitions for functions, objects (like std::cout), and types.

          Everything in the standard library is inside the std namespace. There are no other parts of the standard library outside of the namespace.

  • 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
    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.

    • Alex

      They compile fine as files (as part of another program), but not as standalone programs, since (as you note) there’s no main() function.

  • Luke

    The line after "Most naming collisions occur in two cases:" contains "an function" which, I think, is incorrect. It is not a big problem, I am just pointing it out :).

  • Alessan

    Hi Alex,

    Sorry but I also forgot to mention but if all the identifiers live in namespace std, then why must I include the iostream library aswell. Why not just use the namespace std.

    Thank you very much for the support. This website has helped me tremendously.

    • Alex

      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.

  • Alessan

    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.

    Thank you in advance

    • Alex

      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.

  • Alessan

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

    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.

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

    • Alex

      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.

  • Alex

    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.

    • Alex

      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.

  • My dear c++ Teacher,
    Please let me report you a typo in first phrase, "gaven" instead of "given".
    With regards and friendship.

  • Yuan

    Do we have to add "std::" before those lines in the example? Why?

    • Alex

      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.

  • Alistair

    "Much like a city guarantees that all roads within the city have unique names"

    Nope, there are plenty of Queen’s Roads in Bristol. I think you should consider a different analogy.


    • Alex

      Hmmm, but these Queen’s Roads have different address ranges, right? Otherwise there would be no way to disambiguate them.

      • Alistair

        Address ranges?

        • Alex

          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.

          • Alistair

            Blocks aren’t a thing in the UK, no one planned anything with great concern until the Victorian era.

            No. They are completely different roads. The only way to disambiguate them is to know where they are. They may be on other sides of the city and each start from one.

  • My dear Teacher,
    please let me say that I understand "An example of a naming collision" as follows:

    Output is:
    I beg your comments.
    With regards and friendship.

  • Big"B"LuvRRR

    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

      You could, but doing so makes your code harder to read and remember how to use (e.g. was the function named coutxy0() or coutx0() or coutxy1() or what?).

  • Jim

    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)."

    • Alex

      Not that I’m aware of. Everything in the standard library lives inside the std namespace.

      Perhaps there’s a better word to use than “container”. Maybe “area”?

      • Jim

        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?

        • Alex

          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).

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter