One (.h)eader file to multiple .cpp files

Hi All,

Not sure if I am being really silly but doing learning and it seems that I cant use the same header file in multiple cpp files. It keeps giving linker errors when trying to compile, is this right? All I want to do is centralise some variable data so I can use it across multiple cpp files. Any pointers or help would be greatly appreciated... or another way to achieve this?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

userdata.h

#ifndef  __USER_DATA_H__
#define  __USER_DATA_H__


int target1;
int temps;


#endif // _USER_DATA_H_ 

then in multiple files I do

s1.cpp
#include "userdata.h"

x2.cpp
#include "userdata.h"

z3.cpp
#include "userdata.h"
The problem is that you are defining variables target1 and temps in the header file rather than just declaring that they exist. The way you've coded it, s1, x2 and z3 all allocate space for the two variables. When the linker creates the program, it doesn't know whose space to use.

The way to handle this is to declare the variables in userdata.h and define them in just one of the cpp files. That way only one file allocates space for the variables and the linker knows right where they are:
userdata.h:
1
2
3
4
5
6
7
#ifndef  __USER_DATA_H__
#define  __USER_DATA_H__

extern int target1;
extern int temps;

#endif // _USER_DATA_H_  

s1.cpp:
1
2
3
4
#include "userdata.h"
// define target1 and temps1.
int target1;
int temps1;

x2.cpp:
#include "userdata.h"

z3.cpp:
#include "userdata.h"

Hi dhayden many thanks for the reply. So I take it that extern creates an empty shell and in s1.cpp you initialising them. But it seems that you cant just simply use the value like target1 or temps in code without int? Sorry if it seems a silly question.. Would this be achievable :
s1.cpp
1
2
int target1 = 1;
int temps1 = 1;


x2.cpp
1
2
target1 = 2;
temps1 = 2;


z3.cpp
1
2
target1 = 3;
temps1 = 3;
It's not a silly question. Here's what you do:
Userdata.h:
1
2
3
4
5
6
7
#ifndef  __USER_DATA_H__
#define  __USER_DATA_H__
// Declare target1 and temps1
extern int target1;
extern int temps;

#endif // _USER_DATA_H_   


s1.cpp:
1
2
3
4
#include "Userdata.h"
// initialize target1 and temps1 to 1. This sets them to 1 before main() executes
int target1 = 1;
int temps1 = 1;


x2.cpp:
1
2
3
4
5
6
#include "Userdata.h"
// When this code executes, it changes the values of target1 and temps1 to 2.
void f() {
    target1 = 2;
    temps1 = 2;
}


z3.cpp
1
2
3
4
5
6
#include "Userdata.h"
// When this code executes, it changes the values of target1 and temps1 to 3.
void g() {
target1 = 3;
temps1 = 3;
}



Please note that global variables are widely considered bad practice, regardless of the language you use. Google search "why are global variables bad" and you will find plenty of sources explaining it in detail:

http://c2.com/cgi/wiki?GlobalVariablesAreBad
http://programmers.stackexchange.com/q/148108
http://stackoverflow.com/q/10525582/1959975
https://en.wikipedia.org/wiki/Global_variable
Hey I just wanted to ask why I don't seem to get any errors when I have a header file with declarations like

1
2
3
4
5
6
7
8
9
10
11
// constants.hpp
// no cpp file
// include guards removed for brevity
namespace values {
  const double Pi = 3.14....;
  const double Sqrt2 = 1.4142...
}
namespace headers {
  const std::string Separate   ( "[Separate]" );
  ...
}


I'm pretty sure I'm including it into more than one implementation or other header file, so why doesn't the linker complain about multiple definitions?
Last edited on
Are you sure all the files are actually being compiled and linked together?

If you're using an IDE, the files must be made known to the IDE by adding them to the project tree.

If you're using a commandline compiler, you need to tell the compiler about all the source files (it doesn't look for them for you).
I could be wrong, but aren't constants by nature defined and declared once, and exist in a single memory space? I would think the compiler would treat them differently than non-constants?
Last edited on
Ah, making them const means they are no longer global:
http://stackoverflow.com/a/6173889/1959975

They have internal linkage, so they are unique to the file they are compiled in.
@ Texan40: No, you're absolutely right. That's what is happening.
Yeah they're all in the project tree, and it compiles/runs fine, but no I'm not sure, I guess they aren't actually being linked together or something.

So for maximum compatibility I should be defining constants like Pi as extern and then defining them in a "constants.cpp" file?


EDIT: Oh I saw your other post LB and Texan40, I understand now. Thanks.
Last edited on
We all posted at once - let us review the posts we missed.
Thank you all for your input really useful! Thanks dhayden for the example!
Topic archived. No new replies allowed.