-2

I've got a simple problem I think. But I am unable to solve it so far as I am new to C++ programming. I have created a new C++ project to make the code as short and simple as possible (because the original code is much much longer) while keeping the problem I have. I have searched on Stackoverflow and Google and read about 50 related problems but nothing so far helped me fix it. Putting everything in one cc and one h file works, but is not what I prefer doing. Thanks in advance for the help.

I am using Ubuntu 14.04 / Code::Blocks 13.12 / gcc and g++ 4.8.2

The problem is that I want to access the function inside a class defined in a different file and while compiling works (due to the extern in file1.h) linking fails. If I just put "Simple S1;" instead of "extern Simple S1;" in file1.h and remove it from file1.cc I get a multiple declaration error which is expected. Apparently the "extern" trick doesn't work with classes while it works great with variables.

file1.h:

#ifndef FILE1_H
#define FILE1_H

class Simple
{
    private:
    unsigned int length = 10;

    public:
    void SetLength(unsigned int l) {length = l;}
    unsigned int GetLength() {return length;}
};

extern Simple S1;

#endif

file1.cc:

#include <iostream>
#include "file1.h"
#include "file2.h"

int main()
{
    Simple S1;
    unsigned int l = GetL();
    std::cout << "length=" << l << "\n";
    l = 20;
    l = GetL();
    std::cout << "length=" << l << "\n";
    return 0;
}

file2.h:

#ifndef FILE2_H
#define FILE2_H

unsigned int GetL();

#endif

file2.cc:

#include "file1.h"
#include "file2.h"

unsigned int GetL()
{
    return S1.GetLength();
}

build commands and error:

g++ -std=c++11 -Wall -fexceptions -g  -c file1.cc -o obj/Debug/file1.o
g++ -std=c++11 -Wall -fexceptions -g  -c file2.cc -o obj/Debug/file2.o
g++  -o bin/Debug/Test obj/Debug/file1.o obj/Debug/file2.o   
obj/Debug/file2.o: In function `GetL()':
file2.cc:6: undefined reference to `S1'
collect2: error: ld returned 1 exit status
WillemB
  • 3
  • 3

2 Answers2

0

If S1 is global it must be defined at global scope, not inside main() which creates a new instance local to that function.

Put Simple S1; before main() in your function.

#include <iostream>
#include "file1.h"
#include "file2.h"

Simple S1;

int main()
{
    unsigned int l = GetL();
    std::cout << "length=" << l << "\n";
    l = 20;
    l = GetL();
    std::cout << "length=" << l << "\n";
    return 0;
}
CashCow
  • 30,981
  • 5
  • 61
  • 92
  • Thanks you too for the incredible fast and correct response, I was so focused on the whole class thing which I just added to the code that I failed to see something this obvious. – WillemB Sep 18 '14 at 10:29
  • And I was about a minute ahead of the other answer but you accpeted the other one.. – CashCow Sep 18 '14 at 10:36
  • Sorry I didn't look at that, it just listed the other one first after I checked my question. Did not think I would receive an answer that fast wow. Corrected accepted answer though I would prefer to give you both credits. – WillemB Sep 18 '14 at 10:41
  • Of course an alternative would be to have `GetL()` accept the object it works on: `unsigned int GetL(simple S1){return S1.GetLength();}` and call it with `l=GetL(S1);` – Baldrickk Sep 18 '14 at 12:30
  • The question is asking how to link in a global. I assume the question is simplified. – CashCow Sep 18 '14 at 13:56
0
extern Simple S1;

This declaration promises there is a global object S1 of type Simple somewhere else in the code. But you never define such an object. The "closest" you come to that is the local variable S1 inside main(), but of course, that's an entirely different things.

So just move the definition of S1 outside of main():

Simple S1;

int main()
{
    unsigned int l = GetL();
    std::cout << "length=" << l << "\n";
    l = 20;
    l = GetL();
    std::cout << "length=" << l << "\n";
    return 0;
}
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • Wow thanks for the incredible fast and correct response, I was so focused on the whole class thing which I just added to the code that I failed to see something this obvious. – WillemB Sep 18 '14 at 10:28