89

I know one should not use global variables but I have a need for them. I have read that any variable declared outside a function is a global variable. I have done so, but in another *.cpp file, that variable could not be found. So it was not really global. Isn't it so that one has to create a header file GlobalVariabels.h and include that file to any other *cpp file that uses it?

Freddy Mcloughlan
  • 4,129
  • 1
  • 13
  • 29
Marcus Tik
  • 1,709
  • 6
  • 20
  • 30
  • 4
    @ Lightness Races in Orbit: I need them because I want to exchange data between two functions that don't call each other. – Marcus Tik Mar 14 '12 at 12:47
  • 2
    @MarcusTik: Alright. Be sure to use a namespace, at least. – Lightness Races in Orbit Mar 14 '12 at 12:49
  • "I have done so, but in another *.cpp File that variable could not be found. So it was not realy global." - "Global" means that they are not destroyed until the program ends (as opposed to local variables with block scope that are destroyed when the block ends.) and can be accessed somehow from other translation units. See for details: http://www.learncpp.com/cpp-tutorial/42-global-variables/ – SChepurin Mar 14 '12 at 13:13
  • @SChepurin: "global" scope doesn't say anything about linkage whatsoever. I concede that usage of the term "global" on its own may be inconsistent: that tutorial appears to consider "global" to mean "global scope and linkage", as opposed to "namespace scope" which refers to a TU-local "global". – Lightness Races in Orbit Mar 14 '12 at 13:50
  • @LightnessRacesinOrbit Neither scope nor linkage say anything about storage duration. There is no *global*, TU-local or otherwise. Consider `int foo() { bar = 0; } int bar = 42;`, for example, where most would erroneously refer to `bar` as a *global* variable. How can `bar` be *global* when this code fails to compile? – autistic May 11 '13 at 17:24
  • 1
    @undefinedbehaviour: It is. In that example you introduced a point-of-declaration problem, which is entirely unrelated. – Lightness Races in Orbit Mar 26 '14 at 18:54
  • @LightnessRacesinOrbit You were speaking of "global" scope (much) earlier. bar has file scope, which begins at the point of declaration and ends at the end of the translation unit, as I'm sure you're aware... That's not global scope. – autistic Mar 23 '15 at 02:32
  • @undefinedbehaviour: The problem is that we are talking about terms that are not actually well-defined. I consider file-scope to count as "global". But I can appreciate why you would exclude objects with internal linkage from being "global". Also, I have no idea what we are arguing about any more .... can you clarify what it is that you disagree with (beyond the definition of "global")? – Lightness Races in Orbit Mar 23 '15 at 11:55

5 Answers5

130

I have read that any variable declared outside a function is a global variable. I have done so, but in another *.cpp File that variable could not be found. So it was not realy global.

According to the concept of scope, your variable is global. However, what you've read/understood is overly-simplified.


Possibility 1

Perhaps you forgot to declare the variable in the other translation unit (TU). Here's an example:

a.cpp

int x = 5; // declaration and definition of my global variable

b.cpp

// I want to use `x` here, too.
// But I need b.cpp to know that it exists, first:
extern int x; // declaration (not definition)

void foo() {
   cout << x;  // OK
}

Typically you'd place extern int x; in a header file that gets included into b.cpp, and also into any other TU that ends up needing to use x.


Possibility 2

Additionally, it's possible that the variable has internal linkage, meaning that it's not exposed across translation units. This will be the case by default if the variable is marked const ([C++11: 3.5/3]):

a.cpp

const int x = 5; // file-`static` by default, because `const`

b.cpp

extern const int x;    // says there's a `x` that we can use somewhere...

void foo() {
   cout << x;    // ... but actually there isn't. So, linker error.
}

You could fix this by applying extern to the definition, too:

a.cpp

extern const int x = 5;

This whole malarky is roughly equivalent to the mess you go through making functions visible/usable across TU boundaries, but with some differences in how you go about it.

Tim Tröndle
  • 465
  • 5
  • 12
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
80

You declare the variable as extern in a common header:

//globals.h
extern int x;

And define it in an implementation file.

//globals.cpp
int x = 1337;

You can then include the header everywhere you need access to it.

I suggest you also wrap the variable inside a namespace.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • 2
    I think you should declare the variable type in globals.cpp too, i.e. `int x = 1337`. `int` is the default data type so in this case it will probably work, but... – arne Mar 14 '12 at 12:44
  • nm, I just stumbled over this once and it took me a long time to understand what the compiler actually wanted from me... – arne Mar 14 '12 at 12:50
  • 5
    @arne: There are no "default data types" in C++. – Lightness Races in Orbit Mar 14 '12 at 13:01
  • @LightnessRacesinOrbit: OK, I dimly remember that there was something like that in C. If it isn't in C++, I have to revoke my comment. – arne Mar 14 '12 at 13:19
6

In addition to other answers here, if the value is an integral constant, a public enum in a class or struct will work. A variable - constant or otherwise - at the root of a namespace is another option, or a static public member of a class or struct is a third option.

MyClass::eSomeConst (enum)
MyNamespace::nSomeValue 
MyStruct::nSomeValue (static) 
JTeagle
  • 2,196
  • 14
  • 15
0

Declare extern int x; in file.h. And define int x; only in one cpp file.cpp.

fizzbuzz
  • 159
  • 1
  • 1
  • 8
-3

Not sure if this is correct in any sense but this seems to work for me.

someHeader.h
inline int someVar;

I don't have linking/multiple definition issues and it "just works"... ;- )

It's quite handy for "quick" tests... Try to avoid global vars tho, because every says so... ;- )

Dariusz
  • 960
  • 13
  • 36