(Not) using namespace std;

using namespace std;

This is called a using directive. Using it in code that is supposed to work for years is not a good idea.

Sometimes programmers are given advice to just type using namespace std; and all things from the Standard Library can be used easily, without bothering with namespaces. This is a good advice when you are learning C++ and when you are doing toy examples, or write small private programs. Because for these programs it is not a big deal if they cease to compile once you change the compiler or language version.

using namespace std; makes every symbol declared in namespace std accessible from the global namespace, without namespace qualifiers. You do not know how many names this is, and what those names are. If you upgrade to the newer version of C++, with a bigger Standard Library, you will get even more names “injected” into global namespace: perhaps names that you have already declared yourself in your program.

Suppose you are compiling programs in C++14. Suppose, you are using using namespace std;. At some point you define your type, in the global namespace, called byte. It doesn’t have to be a type: it can be a function. It doesn’t have to be declared in the global namespace: you could declare it in my_namespace and then just do using namespace my_namespace;. And you can use your neat type easily and correctly in your program:

#include <string>
using namespace std;

class byte {};

int main()
{
  byte b;
  // ...
}

Now, after a long anticipation, you migrate your program to C++17. You might not know that C++17 defines enum class byte in namespace std. Maybe you did not expect it in header <string>. But suddenly, name byte becomes ambiguous: you have two of them accessible in the global namespace. If this suddenly happens in many files in a big project, fixing this might become a problem.

This is because using namespace std; means not only “inject all names declared in std even though I do not know all of them”, but also, “whatever names are added to std in the future, even if they clash with my definitions, keep injecting them also”.

Note that in this example I have a problem after putting a using directive in a cpp file. You might have heard people saying, “using directives in headers is bad, but using them in cpp files is ok”. This is not so. Headers only help spread the problem faster, but the problem remains the same in cpp files. And there are other ways of spreading this problem other than header files, such as “best” practices or programmers’ habits.

As an alternative to using namespace std;, it is recommended to either prefix every use of the Standard Library components with std:: or use a using declaration (as opposed to using directive) to only select these names that you intend to use:

#include <string>
using std::string;

This advice, in fact, applies to any namespace that you are not in control of: not only std.

This entry was posted in programming and tagged . Bookmark the permalink.

12 Responses to (Not) using namespace std;

  1. Coder Anonymous says:

    Could not agree more. In fact your exact example (now-conflicting name “byte”) hit us when doing exactly that (upgrading to C++17 compiler).

  2. kobica says:

    I have so many issues convincing people not to use it. Not even in cpp files.

    • Could you, please, elaborate more on why using is bad for cpp files too.

      • The example in the post shows how a using directive in a cpp file spoils the program. Headers are just a means of repeating the same code in many cpp files, but ultimately it is the cpp files. Another way to introduce the problem in multiple cpp files is to invent a policy or a “good” practice that says “do this thing in every source file”.

        • seanboocock says:

          Another way this can crop up, which I have experienced in the past, is the use of “unity” files on large C++ projects (here is a good explanation: http://onqtam.com/programming/2018-07-07-unity-builds/). The side effect is that anything you might have assumed to be private to a compilation unit by virtue of being in a cpp file can now spill into others, and often in unexpected ways.

  3. very good your quite right

  4. rrowniak says:

    It’s quite interesting why so many people are strongly reluctant to follow that advice. It doesn’t introduce much typing, only “std::” but makes your intentions very clear and prevents from the traps described here.

  5. ntysdd says:

    Is it considered too paranoid if I say I will use ::std::string instead of std::string?Should I even use ::std::printf

    • I guess, if you write the end program (as opposed to a library) the extra :: do not buy you much: if their absence spoils something in the program you will notice it immediately and fix the problem locally one way or another.

      However, if you are writing a library, where this may spoil your user’s code, and they cannot fix your library, the case is different. There it makes sense to use ::std::string and others to spare your users problems (rare as they are) that that they cannot fix.

  6. Isto Vilhola says:

    I have just started to study C++ so your article was really useful for me to code clean and precise code. Unlearning is always harder.

  7. Wojciech Toman says:

    Couldn’t agree more (I learnt that the hard way many years ago)! It doesn’t help that most tutorials and books for beginners suggest using that without explaining the consequences.

Leave a reply to Francis Grizzly Smit Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.