0

I have a situation where I need to include a header file (stack.h) in 2 .cpp files.

The set up is as below:

//------"stack.h"------//
std::stack<int> s;
int a;
void doStackOps();
void print();

//------"stack.cpp"------//
#include "stack.h"


//------"main.cpp"------//
#include "stack.h"

Question 1

My header file contains 2 variables and 2 methods. I seem to be getting multiple definition errors only for the variables, why is this the case? Should it not be complaining about the redefinition of the functions as well?

The error looks like :

duplicate symbol _stacks in:
/Users/.....stack.o
/Users/......main.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Question 2

In order to resolve this, the answer suggested for a similar situation here Why aren't my include guards preventing recursive inclusion and multiple symbol definitions? is that we use

inline or static 

where inline is preferred

  • Why is inline preferred over static?
  • inline can only used with functions?

Since I only get the error on the variable, the error goes away when I redefine the stack s as :

static std::stack<int> s; 
static int a; 

Any ideas on what might be happening here? If it helps, I am using Xcode 6. Would really appreciate any help!

Thanks in advance.

Community
  • 1
  • 1
ggog
  • 13
  • 4
  • Do you know what `static` does? (when outside a function or class) – user253751 Feb 23 '15 at 03:10
  • 2
    That's two variable definitions and two function declarations. Redeclarations are fine. – chris Feb 23 '15 at 03:10
  • @immibis : It allocates one piece of memory at compile time for the variable, so there would be no other instances or redefinitions. So I can see why static would work. – ggog Feb 23 '15 at 03:13
  • @chris : I see an error which reads duplicate symbol for architecture x86_64 It finds the same symbol in main.o and stack.o if I don't add the static keyword for the variables. – ggog Feb 23 '15 at 03:15
  • @ggog Nope, completely wrong. It means that variable has file scope. – user253751 Feb 23 '15 at 03:19
  • You probably don't need those variables to be global variables in the first place. – chris Feb 23 '15 at 03:54

1 Answers1

0

There are multiple definition errors because stack.cpp does:

stack<int> s;

and main.cpp also defines a stack:

stack<int> s;

You have two different global objects defined with the same name which causes undefined behaviour (luckily your linker diagnoses it).

Instead, what you probably intended to do was to have a single stack that is referred to by several different units. To accomplish that you can only have the line that defines a stack appear once. (Remember that #include is just a straight text replacement; your code behaves the same as if you copy-pasted the contents of stack.h into the body of each .cpp file).

The other units need to have a line which says "There is a stack<int> called s defined somewhere (but not here)" and the code for that is:

extern stack<int> s;

So you should put that line in your header file, and put stack<int> s; in exactly one .cpp file - doesn't matter which.


In the case of the functions, you do not define any functions in the header, only declare. If you defined a function in the header (e.g. void print() { }) then you would have the same multiple definition error causing undefined behaviour.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • That makes perfect sense.Assume I declare the below in main.cpp extern stack s; Then main.cpp would be populated with all the variables in the project declared as externs, which I don't want. I think am in this situation due to my project setup.Could you please suggest how my project should be structured? Currently, project is dataStructures &files-stack.cpp, stack.h, quickSort.cpp,quickSort.h,mergeSort.cpp,mergeSort.h main.cpp has all the .h's included&I can call any algorithm.What would be the right way to have a single project which has all these files.Suggestions? – ggog Feb 23 '15 at 03:41
  • @ggog i'm not sure what you mean. I described in my answer where things should go. It doesn't matter if an `extern` is visible in a unit that doesn't use it. – M.M Feb 23 '15 at 04:04