@mutexe has given the best advice - "just say no" - no to globals, the use of globals is the root of all evil.
However, if you're just trying to understand what the problem is...
You don't just have 2declarations, you have - and this is a problem - 2definitions
You can declare the same thing numerous times, but you can define it once and only once. A definition is a highlander, there can be only one :-)
To illustrate the difference between the two, here's a quote from Meyer's Effective C++:
A declaration tells compilers about the name and type of something, but it omits certain details. These are
declarations:
1 2 3 4 5
externint x; // object declaration
std::size_t numDigits (int number); // function declarationclass Widget; // class declarationtemplate<typename T>
class GraphNode; // template declaration
A definition provides compilers with the details a declaration omits. For an object, the definition is where compilers
set aside memory for the object. For a function or a function template, the definition provides the code body. For a
class or a class template, the definition lists the members of the class or template:
Global variables are frowned upon these days because global state can be difficult to debug. Avoid it where you can.
In answer to your question though, you should only declare foobar in one file, otherwise the extern is useless.
in the example I would code bar2.cpp as follows..
foobar = 5;
now there is one global variable declared in foo.h, defined in bar.cpp and referenced as an external from bar2.cpp [extern just means external from this translation unit(cpp), ie; it's defined in another cpp file. ]
having multiple copies of the global contradicts the whole point of extern.
is it okay to include header file within a header file?
Lets see ... This is how MSVS12's header file "iostream" starts:
1 2 3 4 5 6 7
// iostream standard header for Microsoft
#pragma once
#ifndef _IOSTREAM_
#define _IOSTREAM_
#ifndef RC_INVOKED
#include <istream>
The header clearly includes another header at line 6. You have been including the iostream in your programs and that has been "okay"? Yes.
Furthermore, when you have a header that contains something like this:
1 2 3 4
class Foo {
std::string bar;
// other code
}
The std::string has to be defined before the definition of Foo. Either those, who include this header, will include "string" before it, or this header includes the "string". The latter is not only "okay" but much more logical and convenient. The "include" directives are handled by the preprocessor and that little helper tool does operate recursively.
Your linker errors are due to multiple compilation units providing definition for same symbol. The very same problem that you had at the start of this thread.
Lorence30, can you tell me what you think the extern keyword does, and why you think you should be using it?
And can you tell me if you are using an OO approach or not?
@mutexe
any variable that declared as extern will be accesible in any file. but it should be defined first in cpp. extern is like a prototype and defining it is like a definition of prototype.
EDIT: i havent learned oop much yet. im just practicing file scopes
any variable that declared as extern will be accesible in any file. but it should be defined first in cpp.
extern is like a prototype and defining it is like a definition of prototype.
I would not use word "any". The latter part is closer to target.
These are declarations. They introduce identifiers (names) with type. They are enough for code in this compilation unit to refer to them, but the referring binary code will be merely a stub that the linker replaces with call to actual implementation during linking:
1 2
externdouble foo;
int bar( std::string );
Only the lines of code in the current compilation unit that are after these declarations can use these identifiers.
These are definitions (implementations). They can be in only one compilation unit that will be linked to the final binary.
1 2 3 4
double foo;
int bar( std::string ) {
// code
}
These are local definitions. They cannot be declared, referred to, nor linked to in other compilation units: