13

I was looking at the google coding guide [here] and they do not recommend that one use the using namespace or namespace::function - if I did not misinterpret it.

Does this apply to std as well? cout<< does not work without it. This book, recommends the same. So how do I go about using cout<< without using namespace std; or std::cout<< ?

What is the recommended way? std::cout<<? Most c++ text books teach beginners with using namespace std; are they propagating poor coding practice?

16

As I read the Google standard, you cannot use the using namespace foo; directive anywhere. This directive brings in everything declared in the namespace and is a common cause of collisions and unexpected behavior. Others have cited a very common one: you have your own max or min method somewhere and it collides in a src file where someone includes a header with your method and then says using namespace std;

In certain places, it is permitted to have a using declaration, which is of the form using ::foo::bar;

People like to put using directives in their code because it saves a lot of typing, but it comes with risk. If you have a file with a lot of cout statements, I can understand not wanting to have to type std::cout a hundred times, but you can simply say using ::std::cout. I treat these like variable declarations: scope them where they are needed. If one function in a file of 10 needs to write output, don't declare the cout way at the top, put it in that function that is doing the actual output.

#include <ostream>
//using namespace std; // NO!
//using ::std::cout;   // less bad than using namespace, but I prefer to scope it

int main(int argc, char** argv)
{
   int rc = do_some_stuff(argc, argv);
   using ::std::endl;
   if (rc) { // print the success report
      using ::std::cout;
      cout << "The test run completed. The return code was " << rc << '.' << endl;
    } else {
      using ::std::cerr;
      cerr << "Unable to complete the test run." << endl;
    }
    return 0 == rc;
}

That's a little extreme with just a couple of lines doing output, but you get the idea.

Another thing one can do is alias or typedef to minimize the typing. I don't find std::whatever to be that bad, but we have a huge set of source with several dozen modules and sometimes we have to write code like console_gui::command_window::append("text"). That gets tedious after a while and causes a lot of long lines. I am all for something like

typedef console_gui::command_window cw;
cw::append("text");

as long as the aliases are done in a local scope and keep enough context to make the code readable.

  • 1
    Thanks! This is really helpful. You not only explained why it is bad with nice examples, but also pointed out solutions with nice examples. :-) – Lord Loh. Apr 25 '14 at 23:57
  • 1
    BTW: Using std::endl for the explicit flush on stdout / stderr is normally quite superfluous, those streams are tied to stdout / stderr anyway. It even slows things down a bit. – Deduplicator Nov 21 '14 at 13:14
8

This is because: 1) it defeats the entire purpose of namespaces, which is to reduce name collision; 2) it makes available to the global namespace the entire namespace specified with the using directive.

For example, if you include and define your own max() function, it will collide with std::max().

http://en.cppreference.com/w/cpp/algorithm/max

The preference is to use std::member_you_wish_to_use because it explicitly states which namespace to use.

  • I presume this means I should use std::max() with the name space prefix. Or am I mistaken? – Lord Loh. Apr 19 '14 at 22:45
  • 3
    It means that if you put "using namespace std;" in your code, you will get errors if you define your own max function (or any other name already defined in the std namespace) – Chewy Gumball Apr 19 '14 at 23:16
  • 1
    It just means that you should be careful with using directives because in this case it would break your max() function if you had defined one and included <algorithm>. This is a simple case but you never know what you might break. You'd need to know the entire library to be sure you didn't break it but you can't know if your code would break (i.e. name collision) in the future. – ApplePie Apr 20 '14 at 0:41
5

Quoting the link you provide:

You may use a using-declaration anywhere in a .cc file, and in functions, methods or classes in .h files.

// OK in .cc files.

// Must be in a function, method or class in .h files.

using ::foo::bar;

Google style forbids you using importing namespaces in global context, but allows to do so in local ones.

Everywhere where using declaration only affects a limited and clearly visible portion of code it is perfectly acceptable.

When you pollute global context, unrelated code is affected (by implicilty using your header). Nothing happens when you do so in local context.

  • We have the same standards. Some of our people will locally typedef a long namespace. e.g. typedef foolicious::barlicious fb; fb::drink d; – Michael Mathews Apr 24 '14 at 21:37
1

they do not recommend that one use the using namespace ornamespace:function` - if I did not misinterpret it.

You did. The disrecommendation only applies to the using namespace directive (which is commonly referred to as abusing namespace, not entirely humorously). It is strongly preferred that you use the fully qualified name of a function or object, such as std::cout.

1

Although the question has already useful answers, one detail seems to fall too short.

Most programmers are at first a bit confused with the using keyword and the descriptions of namespace usage, even if they try to learn it by looking up the reference, because declaration and directive reads somewhat equivalent, both are relatively abstract long words starting with d.

Identifiers within namespaces are accessible by explicitly naming the namespace:

myNamespace::myIdent

this may be a lot more keys to type. But it may also decrease the significance of your code, if most identifiers get prefixed the same way. The using keyword helps to prevent these namespace downsides. Since using works on the compiler level (it's no macro), its effect lasts for the whole scope it is used in. That's why Google style restricts its usage to well defined scopes, i.e. classes in header files or functions in cpp files.

...of course there is a difference between using declaration

using myNamespace::myIdent; // make myIdent an alias of myNamespace::myIdent

and using directive

using myNamespace; // make all identifiers of myNamespace directly accessible

If used in huge scopes, the latter leads to much more confusion.

1

Here you go:

#include <iostream>

int main()
{
    std::endl(std::operator<<(std::cout, "Hello world!"));
}

By writing it this way, we avoid error-prone ADL along with using directives and declarations.

This is meant to be a sarcastic answer. :-D

I'm with Herb Sutter over Google on this one. From C++ Coding Standards:

You can and should use namespace using declarations and directives liberally in your implementation files after #include directives and feel good about it. Despite repeated assertions to the contrary, namespace using declarations and directives are not evil and they do not defeat the purpose of namespaces. Rather, they are what make namespaces usable.

You can obsess about potential namespace conflicts that will probably never manifest and probably won't be difficult to fix in such an astronomically rare event by carefully avoiding using directives and explicitly specifying each and every thing you use (down to the operators) with using declarations, or just go ahead and start using namespace std. I recommend the latter from a productivity standpoint.

Most c++ text books teach beginners with using namespace std; are they propagating poor coding practice?

The opposite if you ask me, and I believe Sutter above agrees.

Now, over the course of my career, I have encountered around 3 namespace conflicts total as a direct result of using directives in codebases spanning tens of millions of LOC. However, in all 3 cases, they were in source files that spanned over 50,000 lines of legacy code, originally written in C and then bastardized to C++, performing a massive eclectic list of disparate functions, including headers from a dozen different libraries, and having an epic list of #includes that spanned over a page. In spite of the epic mess, they weren't too difficult to fix since they caused build errors on OSX (the one OS where the code failed to build), not runtime bugs. Don't organize your code this nightmarish way and you should be fine.

That said, avoid both using directives and declarations in header files. That's just plain retarded. But for source files, and especially ones that don't have a whole page filled with #include directives, I'd say don't sweat it if you aren't working for Google.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.