linker errors (something with namespaces)

May 25, 2010 at 3:59pm
Hello,
this code compiles fine but I can't figure out why do I get linker errors:



-------------- Build: Release in test ---------------

Linking console executable: bin\Release\test.exe
obj\Release\header.o:header.cpp:(.bss+0x0): multiple definition of `global_var'
obj\Release\main.o:main.cpp:(.bss+0x0): first defined here
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 0 seconds)
0 errors, 0 warnings





header.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef HEADER_H
#define HEADER_H


int global_var=0;

namespace DialogX
{
void fa(int y);

}


namespace DialogY
{
void fa(int y);

}

#endif 



header.cpp
1
2
3
4
5
6
7

#include "header.h"


void DialogX::fa(int y){global_var=y;}
void DialogY::fa(int y){global_var=y;}


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "header.h"




int main()
{
DialogX::fa(10);
DialogY::fa(20);




}


Any ideas what's wrong here?
Thanks for help!
May 25, 2010 at 4:01pm
#include copies and pastes stuff from one file to another. That said, your global variable becomes declared in two C++ files.

-Albatross
May 25, 2010 at 4:08pm
May 25, 2010 at 5:10pm
If I recall, the variable can be declared as many times as you want, but only defined once. The ifndef guards only protect against multiple definitions/declarations in the same translation unit (i.e., cpp file in this case), so when main.cpp and header.cpp are compiled, each defines a global variable 'global_var' and assigns it the value '0'. When the executable is linked, it finds 2 variables with the same name in the same scope, and generates an error.

You can fix the above by changing the header to be
extern int global_var;

and adding the below to either main.cpp or header.cpp (but not both!)
int global_var=0;
May 25, 2010 at 6:32pm
What if i declare global_var as static?
May 25, 2010 at 7:01pm
It works, but you won't see the changes to global_var in main.cpp, as each translation unit has its own copy of global_var. This may or may not be what you are trying to achieve.

To illustrate, change main to:

1
2
3
4
5
6
7
8
9
10
int main()
{
cout << global_var << endl;
DialogX::fa(10);
cout << global_var << endl;
DialogY::fa(20);
cout << global_var << endl;

return 0;
}
May 25, 2010 at 7:01pm
Then you get 2 vars. One for each compilation unit.
May 25, 2010 at 7:23pm
Ok, thanks.
May 25, 2010 at 7:32pm
In C, static global variables have module scope. In C++ we use unnamed namespaces for this but the C way is still valid.
Topic archived. No new replies allowed.