I get compile error on global variable.

Hello,

file test.h
1
2
#include"globals.h"
int VAR = 23;


file test.cpp
1
2
3
4
5
6
7
8
9
10
#include<iostream>
#include"test.h"
using namespace std;

int main()
{
	cout << GLOB << endl << flush;
	cout << VAR << endl << flush;
	return 0;
}


file globals.h
 
int GLOB = 100; // No error if it's const 


file globals.cpp
1
2
3
4
5
6
#include"globals.h"

int foo()
{
	return 0;
}


compile and error.
1
2
3
4
g++ -g test.cpp test.h globals.h globals.cpp -o test
/tmp/ccPVNJit.o:(.data+0x0): multiple definition of `GLOB'
/tmp/ccfh0O4a.o:(.data+0x0): first defined here
collect2: ld returned 1 exit status 


So, no error if GLOB is const or if I do not use global.cpp.

How can I use global variable from another header file that also has source file?

Thanks!

Put extern int VAR; in the header and int VAR = 23; in a source file.
I want to use GLOB in test.cpp.
The best solution here is to not use globals. Using globals is bad practice for many reasons, the biggest of which is it makes your code harder to reuse.

A more typical way to share information between functions is to pass the value in question as a parameter.

In your case, I would change your 'foo' function to accept an int parameter. Then you can pass GLOB to it by parameter rather than relying on a global.
Alright, another question, as in the above code, if I have a global variable int GLOB = 100 declared in global.h that I want to use and modify only in global.cpp file, (I also have test.h and test.cpp) but I cannot do it because I have to declare it as const. What to do about it?

Last edited on
The correct solution:
---------------------

- Remove global.h

- Give GLOB a reasonable owner (something with a scope high enough so that the life of the variable is maintained as long as you need it).

- Pass GLOB to functions as a parameter that need to access it as they're needed.

Example:

1
2
// test.h
void foo(int v);

1
2
3
4
5
6
7
// test.cpp
#include "test.h"

void foo(int v)
{
  // do something with 'v' here
}

1
2
3
4
5
6
7
8
// main.cpp
#include "test.h"

int main()
{
  int glob = 100;
  foo(glob);  // foo can do something with glob now.
}



The BAD solution:
-------------------------------

1
2
3
4
5
6
// global.h
#ifndef GLOBAL
#define GLOBAL exter
#endif

GLOBAL int glob;

1
2
3
// global.cpp
#define GLOBAL
#include "global.h" 


I won't explain in detail how this works. Really, you should avoid this.

Trust me. Globals are bad with a capital B.
I have a scenario (greatly simplified) as below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// message.h

// Tags to construct messages.
const string TAG_BEGIN = "begin";
const string TAG_HANDSHAKE = "handshake";
const string TAG_SENDERID = "sender";
//...................
// more than 100 tags!

class message_class
{
public:
	void ConstructHandshake();
//	....................
//	Tens of functions to constract messages.
}


// fix.cpp
#include"message.h"
string message_class::ConstructHandshake(string str)
{
	return TAG_BEGIN + ";" +
		TAG_HANDSHAKE + ";" +		
		SENDERID  + "=" + str + ";";
}


// main.cpp
#include"message.h"
int main()
{
	message_class msg = message_class();
	string str = msg.ConstructHandshake("DEMOCLIENT");
}


As long as the tags are const the project compiles alright. However, I came across a situation when I need to modify few tags inside of message_class. I can move all tags inside of message_class then I would have to declare them and then initialize them in c'tor - that's laborous and error prone considering the large number of tags. Not sure now, make them static?

Just checked, I cannot declare and initialize static string inside of class:

1
2
3
4
static const string TAG_BEGIN = "begin"; // does not compile.
static const int TAG_INT = 99; // compiles.

Any advice? I am trying to avoid declaring and initializing tags in two places.
Last edited on
solved - I used extern.
I just want to emphasize here....

You really should break your habit of using global variables. They are very bad.
That's true but I think it's justifiable because of the sort of problem I have. I can wrap those globals into a namespace.
That's true but I think it's justifiable because of the sort of problem I have.


I find that unlikely, but then again I'm extremely nitpicky ;P

It's your program -- so use your judgement. :)
I'll see how it goes with globals, might change later. Thanks for your help.
Topic archived. No new replies allowed.