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

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

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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

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