Ordering of Using Namespace Std; and Includes

Ordering of using namespace std; and includes?

A perhaps interesting data point. When I compile the following:

using namespace std;
using namespace no_such_namespace;

with g++ 4.5.2, I get:

c.cpp:2:17: error: ‘no_such_namespace’ is not a namespace-name
c.cpp:2:34: error: expected namespace-name before ‘;’ token

To be clear, those two lines are the entire source file I compiled.

Neither std nor no_such_namespace has been defined as a namespace at that point, but g++ complains only about the second. I don't think there's anything special about the identifier std in the absence of a declaration of it. I think @James Kanze is right that this is a bug in g++.

EDIT: And it's been reported. (5 years ago!)

UPDATE: Now it's more than 8 years, and still hasn't been assigned to anyone, much less fixed. g++ 4.9.2 exhibits the problem. clang++ 3.5 doesn't, but it issues a warning for std and a fatal error for no_such_namespace:

c.cpp:1:17: warning: using directive refers to implicitly-defined namespace 'std'
using namespace std;
^
c.cpp:2:17: error: expected namespace name
using namespace no_such_namespace;
^
1 warning and 1 error generated.

UPDATE: As of 2021-09-24, the bug report is still open and the bug exists in g++ 11.2.0. A comment posted 2021-07-24 suggests that g++ should warn about this.

C++: Questions about using namespace std and cout

cout is a global object defined in the std namespace, and endl is a (stream manipulator) function also defined in the std namespace.

If you take no action to import their names into the global namespace, you won't be able to refer to them with the unqualified identifiers cout and endl. You have to use the fully qualified names:

std::cout << "Hello, World!" << std::endl;

Basically, what using namespace std does is to inject all the names of entities that exist in the std namespace into the global namespace:

using namespace std;
cout << "Hello, Wordl!" << endl;

However, keep in mind that have such a using directive in the global namespace is a BAD programming practice, which will almost certainly lead to evil name clashes.

If you really need to use it (e.g. if a function of yours is using many functions defined in the std namespace, and writing std:: makes the code harder to read), you should rather restrict its scope to the local scope of individual functions:

void my_function_using_a_lot_of_stuff_from_std()
{
using namespace std;
cout << "Hello, Wordl!" << endl;

// Other instructions using entities from the std namespace...
}

Much better, as long as this is practical, is to use the following, less invasive using declarations, which will selectively import only the names you specify:

using std::cout;
using std::endl;

cout << "Hello, Wordl!" << endl;

Why is using namespace std; considered bad practice?

Consider two libraries called Foo and Bar:

using namespace foo;
using namespace bar;

Everything works fine, and you can call Blah() from Foo and Quux() from Bar without problems. But one day you upgrade to a new version of Foo 2.0, which now offers a function called Quux(). Now you've got a conflict: Both Foo 2.0 and Bar import Quux() into your global namespace. This is going to take some effort to fix, especially if the function parameters happen to match.

If you had used foo::Blah() and bar::Quux(), then the introduction of foo::Quux() would have been a non-event.

using namespace std; in a header file

Let's say I declare a class string myself. Because I'm a lazy bum, I do so in global namespace.

// Solar's stuff
class string
{
public:
string();
// ...
};

Some time later on, I realize that re-using some of your code would benefit my project. Thanks to you making it Open Source, I can do so:

#include <solarstuff.hpp>
#include <phoenixstuff.hpp>

string foo;

But suddenly the compiler doesn't like me anymore. Because there is a ::string (my class) and another ::string (the standard one, included by your header and brought into global namespace with using namespace std;), there's all kinds of pain to be had.

Worse, this problem gets promoted through every file that includes my header (which includes your header, which... you get the idea.)

Yes I know, in this example I am also to blame for not protecting my own classes in my own namespace, but that's the one I came up with ad-hoc.

Namespaces are there to avoid clashes of identifiers. Your header not only introduces MyStuff into the global namespace, but also every identifier from string and fstream. Chances are most of them are never actually needed by either of us, so why dragging them into global, polluting the environment?

Addition: From the view of a maintenance coder / debugger, foo::MyStuff is ten times more convenient than MyStuff, namespace'd somewhere else (probably not even the same source file), because you get the namespace information right there at the point in the code where you need it.

C/C++ include header file order

I don't think there's a recommended order, as long as it compiles! What's annoying is when some headers require other headers to be included first... That's a problem with the headers themselves, not with the order of includes.

My personal preference is to go from local to global, each subsection in alphabetical order, i.e.:

  1. h file corresponding to this cpp file (if applicable)
  2. headers from the same component,
  3. headers from other components,
  4. system headers.

My rationale for 1. is that it should prove that each header (for which there is a cpp) can be #included without prerequisites (terminus technicus: header is "self-contained"). And the rest just seems to flow logically from there.

Why do I need to do 'using namespace std' instead of 'using std::cout'?

Your code works okay with:

using std::cout;

statement for cout, but the compiler must know the location of string (actually it's std::string) too which you're currently using. You must define:

using std::string;

When you enter:

using namespace std;

It calls the entire namespace called std which contains a variety of features added as C++ standard library and then you don't need to use prefix std:: for those functions/classes/variables of that namespace.



Related Topics



Leave a reply



Submit