tags:

views:

235

answers:

3

This is from the <iostream>:

namespace std 
{
  extern istream cin;       ///< Linked to standard input
  extern ostream cout;  
...

It seems by using extern the data types defined in other namespaces will just be available?

+2  A: 

No, this is an explicit way to say cin and cout are declared without actually defining them.

Eli Bendersky
+4  A: 

extern means "these variables are defined in some other compilation unit (.cpp or .lib file)"

In this case, you #include <iostream> into your .cpp file, and because cin and cout are declared as extern, the compiler will let you use them without complaining. Then, when the linker runs, it looks up all of the extern variables and sorts it all out.

Dean Harding
Does it mean `istream` or `cin` is defined in some other unit in the case of `extern istream cin;`?
symfony
It means `cin` is. This is not the same thing as the *class definition*, which in this case, is in `iostream`. The *class definition* must always be available in a compilation unit to use objects of that class' type (this is why class definitions are put into *header* files).
@STingRaySC ,can you elaborate a little?I'm confused a lot..
symfony
`cin` and `cout` are global variables. In C++, a global variable must be declare in one and only one .cpp file (with some exceptions). So if you just said `istream cin` then the linker would complain when you go to link two files which both declare the variable because it wouldn't know which one to use. So by declaring all but one of them as `extern`, you tell the linker to use the non-`extern` as the "real" one, and the `extern` ones just say "this variable is declared in some other .cpp file".
Dean Harding
@codeka -- the distinction between *declare* and *define* is critical to understanding this. Please get it right! They are not synonymous.
+1  A: 

extern is used to refer to a variable defined in a different compilation unit (for now, you can think of a compilation unit as a .cpp file). The statements in your example declare rather than define cin and cout. It is telling the compiler that the definition of these objects is found in another compilation unit (where they are not declared as extern).

But I don't find anywhere that define `cin`,only `istream` is defined in `<iosfwd>`
symfony
`cin` is an object of type `istream`. `istream` is the class (in this case, template class) definition. `cin` is an instance of the `istream` class. The "definition" I refer to in my answer is the definition of `cin`, not `istream`. You need to look up the meaning of *definition* vs. *declaraion*. The statements in your examples are *declarations*.
The *definition* of the `cin` variable is most likely in a run-time library. You won't find it in the standard library header files.
@STingRaySC ,is there a trick to find where it's actually defined?
symfony
@symfony: No. It's defined in code that's already been compiled into a library that you will link your code with. In general, a variable referred to by an `extern` declaration can be defined in **any** compilation unit that is made available to the linker (in the form of a compiled object file).