views:

2911

answers:

10

Why do we need both using namespace and include directives in C++ programs ?

For example,

#include <iostream>

using namespace std;

int main() {
 cout << "Hello world";
}

Why is it not enough to just have #include or just have "using namespace std" and get rid of the other ?

(I am think of an analogy with Java, import java.net.* will import import everything from java.net, you don't need to do anything else.)

+7  A: 

In C++ the concepts are separate. This is by design and useful. You can include things that without namespaces would be ambiguous. With namespaces you can refer to two different classes that have the same name. Of course in that case you would not use the 'using' directive or if you did you would have to specify the namespace of the other stuff in the namespace you wanted.

Note also that you don't NEED the using - you can just used std::cout or whatever you need to access. You preface the items with the namespace.

Tim
+3  A: 

In C++ #include and using have different functions.

#include puts the text of the included file into your source file (actually translation unit), namespaces on the other had are just a mechanism for having unique names so that different people can create a "foo" object.

This comes from C++ not having the concept of a module.

Keep in mind that namespaces in C++ are open, that means that different files can define different parts of the same namespace (sort of like .NET's partial classes).

//a.h
namespace eg {
    void foo();
}

//b.h
namespace eg {
    void bar();
}
Motti
+2  A: 

The include is defining the existence of the functions.

The using is making it easier to use them.

cout as defined in iostream is actually named "std::cout".

You could avoid using the namespace by writing.

std::cout << "Hello World";
James Curran
+1  A: 

You need to understand namespaces if you want to truly understand this.

With include you are just including the header file.

With using namespace you are declaring you are using a given namespace that contains stuff such as cout. so if you do this:

using namespace std;

to you use cout you can just do

cout << "Namespaces are good Fun";

instead of:

std::cout << "Namespaces are Awesome";

Note that if you do not #include <iostream> you won't be able to use neither std::cout nor cout in your declarations and so forth because you're not including the header.

JohnIdol
Shouldn't that be <string>, not <iostream>?
Harper Shelby
making confusion - sorry edited
JohnIdol
+2  A: 

These keywords are used for different purposes.

The using keyword makes a name from a namespace available for use in the current declarative region. Its mostly for convenience so that you do not have to use the fully qualified name all the time. This page explains it in some detail.

The #include statement is a pre processor directive and it tells the preprocessor to treat the contents of a specified file as if those contents had appeared in the source program at the point where the directive appears. That is, you can think of this statement as copying the included file into the current one. The compiler then compiles the entire file as if you wrote all the code in one big file.

Vincent Ramdhanie
+2  A: 

I think the other answers are missing the point slightly. In all of C++, Java and C#, the using/import thing is entirely optional. So that's not different.

And then you have to do something else to make code be visible anyway, in all three platforms.

In C++, you minimally have to include it into the current translation unit (good enough for many implementations of vector, string, etc.), often you have to add something to your linker as well, although some libraries do that automatically based on the include (e.g. boost when building on Windows).

And in C# you have to add a reference to the other assembly. That takes care of the equivalent of includes and link settings.

And in Java you have to ensure the code is on the classpath, e.g. adding the relevant jar to it.

So there are very closely analogous things required on all three platforms, and the separation between using/import (a convenience) and actual linkage resolution (a requirement) is the same in all three.

Daniel Earwicker
+5  A: 

using directives and include preprocessor directives are two different things. The include roughly corresponds to the CLASSPATH environment variable of Java, or the -cp option of the java virtual machine.

What it does is making the types known to the compiler. Just including <string> for example will make you able to refer to std::string :

#include <string>
#include <iostream>

int main() {
    std::cout << std::string("hello, i'm a string");
}

Now, using directives are like import in Java. They make names visible in the scope they appear in, so you don't have to fully qualify them anymore. Like in Java, names used must be known before they can be made visible:

#include <string> // CLASSPATH, or -cp
#include <iostream>

// without import in java you would have to type java.lang.String . 
// note it happens that java has a special rule to import java.lang.* 
// automatically. but that doesn't happen for other packages 
// (java.net for example). But for simplicity, i'm just using java.lang here.
using std::string; // import java.lang.String; 
using namespace std; // import java.lang.*;

int main() {
    cout << string("hello, i'm a string");
}

It's bad practice to use a using directive in header files, because that means every other source file that happens to include it will see those names using unqualified name lookup. Unlike in Java, where you only make names visible to the package the import line appears in, In C++ it can affect the whole program, if they include that file directly or indirectly.

Be careful when doing it at global scope even in implementation files. Better to use them as local as possible. For namespace std, i never use that. I, and many other people, just always write std:: in front of names. But if you happen to do it, do it like this:

#include <string>
#include <iostream>

int main() {
    using namespace std;
    cout << string("hello, i'm a string");
}


For what namespaces are and why you need them, please read the proposal Bjarne Stroustrup gave 1993 for adding them to the upcoming C++ Standard. It's well written:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0262.pdf

Johannes Schaub - litb
+1  A: 

As pointed out, C++ and Java are different languages, and do somewhat different things. Further, C++ is more of a 'jest grew' language, and Java more of a designed language.

While using namespace std; isn't necessarily a bad idea, using it for all namespaces will eliminate the whole benefit. Namespaces exist so that you can write modules without regard to name clashes with other modules, and using namespace this; using namespace that; can create ambiguities.

David Thornley
Java was originally designed (and C++ in the early '80s was "designed"), but I have a hard time believing Java from today fits any definition of "designed."
Max Lybbert
+1  A: 

Even Stroustrup refers to the #include mechanism as somewhat hackish. However it does make separate compilation much easier (ship compiled libraries and headers instead of all source code).

The question really is "why did C++ -- after it already had the #include mechanism -- add namespaces?"

The best example I know of about why #include isn't enough comes from Sun. Apparently Sun developers had some trouble with one of their products because they had written a mktemp() function that happened to have the same signature as a mktemp() function that was included through from a file that was itself included through a header the project actually wanted.

Of course the two functions were not compatible, and one could not be used as a substitute for the other. On the other hand, the compiler and linker did not realize this when building the binary, and sometimes mktemp() would call one function, and sometimes it would call another, based on the order different files were compiled or linked.

The problem stems from the fact that C++ was originally compatible with -- and essentially piggy-backed on top of -- C. And C has only a global namespace. C++ solved this problem -- in code that is not compatible with C -- through namespaces.

Both C# and Java (1) have a namespace mechanism (namespace in C#, package in Java), (2) are usually developed through IDEs that handle referring to binaries for the developer, and (3) don't allow freestanding functions (a class scope is something of a namespace, and reduces the risk of polluting the global namespace) so they have a different solution to this problem. However, it is still possible to have some ambiguity regarding which method you're calling (say, a name clash between two interfaces that a class inherits), and in that case all three languages require the programmer to clearly specify which method they're actually looking for, usually by prepending the parent class/interface name.

Max Lybbert
A: 

One liner (not that this is something new :)):

using std allows you to omit std:: prefix, but you cannot use cout at all without iostream.

PolyThinker