Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undefined Reference to <namespace>::<variable> [closed]

Tags:

c++

I'm working on some code to flag when changes have been made to a website. I've run into a problem using a static variable in the class, so I want to declare a variable in the namespace and set this ==1 when a change is made.

Here is some simplified code that I've written to represent the problem:

p.h:

#include<iostream>
using namespace std;

#ifndef p_H
#define p_H
namespace testing{

 extern int changes_made;

 class p 
 {
   public: 
     void changed();
     void print_change();
     void print_change_ns();
   private:
     static int changes;
     int info;
};

}
#endif

p.cpp:

 #include "p.h"
#include<iostream>

using namespace testing;

int p::changes=0;

void p::changed(){
    p::changes=1;
    }

void p::print_change(){
    cout << p::changes << endl;
    }

void p::print_change_ns(){
    if (testing::changes_made == 1){
    cout << 1 << endl;
    }
    else{
    cout << 0 << endl;
    }
    }

main.cpp:

#include<iostream>
#include"p.h"

using namespace std;
using namespace testing;


int main(){

p test1, test2, test3;
test3.changed();
changes_made=1;

cout << "test1 ";
test1.print_change();
test1.print_change_ns();

cout << "test2 ";
test2.print_change();
test2.print_change_ns();

cout << "test3 ";
test3.print_change();
test3.print_change_ns();

p test4;
cout << "test4 ";
test4.print_change();
test4.print_change_ns();
return 0;
}

I get the following error messages:

p.o: In function `testing::p::print_change_ns()':
p.cpp:(.text+0x45): undefined reference to `testing::changes_made'
main.o: In function `main':
main.cpp:(.text+0x9b): undefined reference to `testing::changes_made'
collect2: ld returned 1 exit status

Any help on this would be greatly appreciated. I previously had multiple declaration errors so I introduced the #ifndef stuff, and also the extern before the variables.

like image 222
James Avatar asked Dec 17 '12 15:12

James


2 Answers

extern variables like extern int changes_made; need to have their storage created somewhere. What you have stated is "at the linking stage, you will find that someone will export you a symbol of this name of type int".

Then you failed to follow through on the promise, because no unit exports int testing::changes_made.

In some .cpp file that you are linking with the above p.cpp and main.cpp (maybe even p.cpp), create an instance of the variable like this:

namespace testing {
  int changes_made = 0;
}

and your linker error should go away.

like image 163
Yakk - Adam Nevraumont Avatar answered Nov 13 '22 18:11

Yakk - Adam Nevraumont


You have declared testing::changes_made in the header file; but you haven't defined it. You also need a definition in exactly one source file (probably p.cpp):

int testing::changes_made; // no "extern"
like image 3
Mike Seymour Avatar answered Nov 13 '22 19:11

Mike Seymour