2

I know global is bad but just as a practice, is this the correct way to initialize a global class used between multiple object files?

Header 1.h

class test {
 int id;
 public:
 test(int in){
   id = in;
 }
 int getId(){
  return id;
 }
};

extern test t;

File 1.cc:

#include <iostream>
#include "1.h"

int main(){
 std::cout << t.getId() << std::endl;
 return 0;
}

File 2.cc:

#include "1.h"

test t(5);

Now what if instead of extern I use the static approach globally static test t(0); in the header?

Correct me if I'm wrong but that would compile fine however I would have 2 different unrelated copies of the same t in both object files and the final binary? Is that bad? Or does the linker sort it out to eliminate multiple copies?

Christophe
  • 68,716
  • 7
  • 72
  • 138
Josh
  • 21
  • 2

5 Answers5

5

There are global instances, not global classes.

What you have is a global instance. And yes, this sounds about right, until you get to multiple global instances which depend upon each other. Then the real fun will start.

Tanveer Badar
  • 5,438
  • 2
  • 27
  • 32
1

Defining a variable as 'static' at global level means the variable will be defined in the compilation unit only (i.e. the '.o' file) and the symbol won't be exported by the compiler.

In other words: yes, there will be multiple variables with the same name but only visible to functions on the same compilation unit.

Besides, 'invisible' doesn't mean 'inaccessible'. You still can provide access to the variable. For example:

1.h

struct Test { int value; };         // Class definition
Test& get_t();                      // Function declaration

1.cc

#include "1.h"
static Test t;                      // Variable declared as 'static'
Test& get_t() { return t; };

2.cc

#include "1.h"
#include <iostream>
int main()
{
  std::cout << get_t().value << std::endl;  // Static variable accessed
}
JL. Sanchez
  • 371
  • 1
  • 7
  • So basically rely on the memory address. But this doesn't seem like a proper way right? `extern` seems to be a better choice for declaring global variables. – Josh Jan 21 '20 at 18:29
0

I use the static approach globally static test t;?

But your test class needs an int in parameter for the constructor, so you want:

static test t(0); // or whatever int you want
Paul Evans
  • 27,315
  • 3
  • 37
  • 54
0

If you turn the extern to static in the header, you would define a static variable in each compilation unit in which the header is imported. So classes in different cpp files would no longer "communicate" via t, since each would have theirs. This is very error prone.

In addition, adding the definition of a static in a header is an extremely bad practice. When someone includes a header, one does not expect that it will create variables.

Including the declaration of t as extern is an acceptable practice. But be aware that if the header has a general purpose, this might reduce its reusability other projects.

More information of interest for you:

Christophe
  • 68,716
  • 7
  • 72
  • 138
0

If you put a variable declaration outside of any function, you're declaring the variable as 'global'. Ex:

1.cc

int this_is_global;

From here on you can use the variable in any function of '1.cc'.

For using the same variable in any other file, the compiler will need to know about it:

2.cc

extern int this_is_global;

Here, the keyword extern tells the compiler that the variable is declare somewhere else, letting the task of finding it to the linker.

If you miss to add the extern keyword here, the compiler will treat it as a new variable, and the linker will have two variables with the same name and will emit an error. All of your source files of your project except the first one will need the extern keyword to avoid duplicate symbols.

So common practice is to add the 'extern' declaration in an include file:

1.cc

int this_is_global;

1.h

extern int this_is_global;

2.cc

#include "1.h"

On the other side, the static keyword tells the compiler not to export the symbol. In other words: the variable will exists only in the source file it is declared. You could declare it once per source file and there will be different variables with the same name. Ex:

1.h

static int my_var;

1.cc

#include "1.h"

2.cc

#include "1.h"

This way, you'll end having two variables 'my_var' and changes to any of them won't affect the other.

JL. Sanchez
  • 371
  • 1
  • 7