0

I am trying to understand namespace std. I know what a namespace is. I want to know, is namespace std defined in multiple header files?

I have two sample codes here, and they both compile and run fine. One uses #include<string> and the other uses #include<iostream>. Both use "using namespace std". This tells me that std is defined in both headers, is that right? If so, then when I use both headers in the same code, how will the compiler know which std to use?

CODE 1:

#include <string> 
using namespace std;

int main()
{ 
    string test;
    test = "hello"; 
    return 0; 
} 

CODE 2:

#include <iostream> 
using namespace std;

int main()
{ 
    string test; 
    test = "hello"; 
    return 0; 
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
frank_crane
  • 177
  • 2
  • 9
  • What if you don't include anything? – Ali Tou Aug 07 '21 at 18:51
  • 1
    If something is defined in `std` namespace like so `namespace std { struct something; }`, then *the full* name of it is `std::something`. So having `namespace std {}` in multiple headers does nothing bad, just everything defined will have the same prefix `std::` – Alexey S. Larionov Aug 07 '21 at 18:58
  • Different headers put different things into `namespace std`. – Galik Aug 08 '21 at 00:01

4 Answers4

5

A namespace is open; that is, you can add names to it from several separate namespace declarations. For example:

namespace A {
   int f();
}
namespace A {
  int g();
}
grigouille
  • 511
  • 3
  • 14
2

All namespaces with the same name (and in the same scope) are unified to one, so the compiler doesn’t have to choose.

Daniel
  • 30,896
  • 18
  • 85
  • 139
1

"this tells me that std is defined in both the headers. is that right?"

The headers include parts of the standard library. Both, iostream and string belong to the standard library, and each of them provides a different set of commands that can be addressed with std::.

The insertion of using namespace resolves the scope, which means that the compiler searches for a function or a command within std::: if it is not found in an inner scope. Therefore, instead of, e.g., writing std::cout << "Hello world" << std::endl; you can simply write cout << "Hello world" << endl; (assuming that iostream is included). This shortens and simplifies the writing of the code, but it can also have disadvantages, which is why using namespace std is generally considered bad practice.

Some headers of the standard library are included indirectly when another header is included. This appears to be the case in your Code2, which compiles although #include<string> is missing.

One cannot rely on such indirect inclusions. More information on this topic can be found here: Do I have to use #include <string> beside <iostream>?

RHertel
  • 23,412
  • 5
  • 38
  • 64
  • 1
    It's not "`std::` by default". It's `std::` if you can't find it in an inner scope. – Pete Becker Aug 07 '21 at 19:24
  • @PeteBecker Thanks for the comments. I corrected the "default" statement and added a warning on the use of "using namespace std". – RHertel Aug 07 '21 at 20:02
1

I know what a namespace is.

Perhaps you do, perhaps not exactly. A namespace is a tool used to prevent naming conflicts. Everything belonging (directly) to a namespace is public, as public identifiers are the only ones that can conflict with code outside the namespace. Unlike a class, there is no encapsulation or data integrity concerns to address; such concerns are relegated to the classes within the namespace.

This open nature of namespaces means that, unlike class definitions, a namespace definition need not be complete. All you need is for (the teams working on) the pieces of the namespace to coordinate their naming schemes. This is why it is typically wrong to add something to someone else's namespace. Since you are not part of the coordination, you could inadvertently introduce a conflict, perhaps quietly introducing undefined behavior, no diagnostic required.

Syntactically, though, you can add to any namespace. This is a useful feature, since traditionally one creates a header file for each class, and namespaces often span more than one class. So it is often desired for a namespace to span multiple header files. How to use namespace across several files? Just use the same namespace name in each namespace definition. A namespace definition is not so much a "definition" as it is a "tour". It is more "this is part of the namespace" than "this is the namespace". The more tours/parts you see, the more complete your view.

On the subject of incomplete views of a namespace, see Can the definition of a namespace span multiple translation units? (Hopefully you guessed "yes".)

I want to know, is namespace std defined in multiple header files?

Yes. The C++ standard dictates dozens of header files that must exist, and implementations are allowed to break those into auxiliary headers. See cppreference.com for a list of the required headers; the ones listed before the "C compatibility headers" section collectively define the std namespace.

JaMiT
  • 14,422
  • 4
  • 15
  • 31