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 gaven 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 an function (or global variable) with the same name (linker error).
2) A code file includes a header file that contains a 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

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

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

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

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

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

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

Leave a Comment

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