Undefined reference when using a function included in a header file [duplicate] - c++

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 5 years ago.
I am experiencing something weird with my c++ source file or perhaps the compiler itself. It seems that when I attempt to compile the file, it hits me with a message -
undefined reference to "Basic_int_stack::Basic_int_stack()
undefined reference to "Basic_int_stack::Push(int)
Here is my code (I'm still a beginner so don't expect any crazy professional code )
Header file:
class Basic_int_stack
{
public:
// This part should be implementation independent.
Basic_int_stack(); // constructor
void push( int item );
int pop();
int top();
int size();
bool empty();
private:
// This part is implementation-dependant.
static const int capacity = 10 ; // the array size
int A[capacity] ; // the array.
int top_index ; // this will index the top of the stack in the array
};
Implementations:
#include "basic_int_stack.h"// contains the declarations of the variables and functions.
Basic_int_stack::Basic_int_stack(){
// the default constructor intitializes the private variables.
top_index = -1; // top_index == -1 indicates the stack is empty.
}
void Basic_int_stack::push( int item ){
top_index = top_index + 1;
A[top_index] = item ;
}
int Basic_int_stack::top(){
return A[top_index];
}
int Basic_int_stack::pop(){
top_index = top_index - 1 ;
return A[ top_index + 1 ];
}
bool Basic_int_stack::empty(){
return top_index == -1 ;
}
int Basic_int_stack::size(){
return top_index;
}
Main Function:
#include "basic_int_stack.h"
#include <iostream>
int main()
{
int var;
Basic_int_stack s1;
while((std::cin >> var)>=0){
s1.push(var);
}
return 0;
}

This is happening because you're building your main file without building and linking your class implementation file as well. You need to adjust your build settings somehow.

It is because you don't include Basic_int_stack.cpp when you complile.
Simplely speaking, when you encounter Undefined reference to xxx, it is a error generated by linker, when means the compliler can't find the implements. So you need check if you include the cpp file or dynamic library or static library.

I faced the same problem. Finally I found a fix by including .cpp file in the main file.
#include "file_name.cpp" //In the main file

Related

Linking error in c++ (multiple cpp files) [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 2 years ago.
I'm making a prime generator with 3 file (two of them are .cpp and one is .h).
However when i try to build the whole project it in onlinegdb gives this error
/tmp/ccI5GCGK.o: In function `main':
main.cpp:(.text+0x11f): undefined reference to `int primegen(int&, long*, long*)'
collect2: error: ld returned 1 exit status
main.cpp
#include <iostream>
#include "primegen.h"
int main(void)
{
//taking input for number of test cases
int test_case{2};
long int lower_lim[MAX] = {5, 15}, upper_lim[MAX] = {15, 25};
//function present in primefunc.cpp
primegen(test_case,lower_lim,upper_lim);
}
primefunc.cpp
// to make SUCCESS known to this file
extern int SUCCESS;
//main function to prime generator between limits
int primegen(int &test, auto *low, auto *up)
{
static int cases=0;
if(cases == test)
return SUCCESS;
int diff=up[cases]-low[cases];
for(int i=0;i<diff;i++)
{
//some code to be added
}
}
primegen.h
// for making arrays of lower and upper limit
constexpr int MAX = 10;
constexpr int SUCCESS = 2;
// for printing out prime number
int primegen(int &, auto *, auto *);
EDIT :- I tried moving the function from the 2nd cpp to the main.cpp and it worked and also individual builds also gives success.

Compiler error in introductory C++ example program [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 2 years ago.
I'm having some difficulty reproducing an example program of Object-Oriented Programming Using C++ described in "Encapsulation and Type Extensibility."
For simplicity's sake, I've cut out most of the code to focus on the specific error at hand:
#include <iostream> // Access standard IO library
#include <string> //Access type 'string'
using namespace std; //Use standard library namespace
const int max_length = 255;
class my_string {
public:
void assign(const char* st);
int length() const { return len; }
void print() const
{ cout << s << "\nLength: " << len << endl; }
private:
char s[max_length];
int len;
};
int main()
{
my_string one;
one.assign("I'm sorry Dave, I'm afraid I can't do that.");
one.print();
system("PAUSE");
}
When I try to compile, I get the error message:
[Linker error] undefined reference to 'my_string::assign(char const*)'
I'm not sure what I'm doing wrong. My best guess is that assign is incorrectly defined, since the main() block seems fine.
Edit:
The complete example as written in the book is:
In file string1.cpp
const int max_len = 255;
class my_string {
public:
void assign(const char* st);
int length() const { return len; }
void print() const
{ cout << s << "\nLength: " << len << endl; }
private:
char s[max_length];
int len;
};
int main()
{
my_string one, two;
char three[40] = {"My name is Charles Babbage."};
one.assign("My name is Alan Turing.");
two.assign(three);
cout << three;
cout << "\nLength: " << strlen(three) << endl;
if (one.length() <= two.length())
one.print();
else
two.print();
}
Linking and compiling errors are two different things. A compiler error means that you did something wrong in the syntax.
A linking error tells you that there is a part missing when the linker tries to put your program together.
[Linker error] undefined reference to 'my_string::assign(char const*)'
This error tells you that somewhere the promise was made to the compiler that my_string::assign(char const*) exists and can be used (by a declaration void assign(const char* st);). But in the linking step the linker cannot find that function.
If the error references a function that you have written, then you might have forgotten the definition of it or have mismatching signature between declaration and definition.
The compiler can't find it's definition.
Usually there is a header file (.h) where the class' declaration is put, including as less as possible and a source file (.cpp) that includes all the definitions.
The header file declarations tells the compiler which methods shall be available (as a promise),
the source file should contain the definition of the functions that are declared in the header file.
If they aren't defined, meaning there is no body for that function, it can't be executed. In your book, the code is both declared and defined, by writing the methods inside the class' definition.
You could do the same:
public:
void assign(const char* st) {
/* implementations of the assign method here
(or leave it empty for this example, but rather don't)*/
};
int length() const { return len; };
...

Undefined reference error when compiling with g++ compiler in cygwin

I'm just starting to work on a project for class and I'm getting an error that I'm unsure how to fix. I'll do my best to provide all necessary details but if you need any more info please let me know. The project is to create a simple hash function and I'm getting a linker error when trying to compile. I will post all of my code as well as the error I receive when compiling. I have taken two previous programming classes but that was quite a while ago and I'm pretty out of practice at the moment so it may be an obvious mistake. Ignore all commented out code in hash.h because that is just function definitions that my teacher provided that I have not yet implemented. She also specifically requested that we put our hashing function in its own separate file. I should also specify that I'm using a Windows machine with cygwin64 to compile my code.
hash.h:
#ifndef __HASH_H
#define __HASH_H
#include <string>
#include <list>
using std::string;
using std::list;
class Hash {
public:
void remove(string); // remove key from hash table
//void print(); // print the entire hash table
void processFile(string); // open file and add keys to hash table
//bool search(string); // search for a key in the hash table
//void output(string); // print entire hash table to a file
//void printStats(); // print statistics
private:
// HASH_TABLE_SIZE should be defined using the -D option for g++
//list<string> hashTable [HASH_TABLE_SIZE];
list<string> hashTable [100];
int collisions;
int longestList;
double avgLength;
int hf(string); // the hash function
void insert(string);
// put additional variables/functions below
// do not change anything above!
};
#endif
hash.cpp:
#include "hash.h"
void Hash::remove(string string_to_remove)
{
int index = hf(string_to_remove);
for(list<string>::iterator iter = hashTable[index].begin(); iter != hashTable[index].end(); iter++)
{
if(*iter == string_to_remove)
hashTable[index].erase(iter);
}
}
void Hash::insert(string string_to_add)
{
int index = hf(string_to_add);
hashTable[index].push_back(string_to_add);
}
void Hash::processFile(string file_name)
{
insert(file_name);
}
hash_function.cpp
#include "hash.h"
int Hash::hf(string input)
{
int sum = 0;
for (int i = 0; i < 5; i++)
sum += (int)input[i];
cout << sum % 100 << endl;
return [sum % 100 /*HASH_TABLE_SIZE*/];
}
Compiler Error:
$ g++ hash_function.cpp testmain.cpp hash.cpp -o test
/tmp/cc42z5XM.o:hash.cpp:(.text+0x32): undefined reference to `Hash::hf(std::string)'
/tmp/cc42z5XM.o:hash.cpp:(.text+0x32): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Hash::hf(std::string)'
/tmp/cc42z5XM.o:hash.cpp:(.text+0x13c): undefined reference to `Hash::hf(std::string)'
/tmp/cc42z5XM.o:hash.cpp:(.text+0x13c): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Hash::hf(std::string)'
collect2: error: ld returned 1 exit status

Strange "Undefined symbols" error?

I am learning C++ and I got this error:
Undefined symbols:
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
my code is this
#include <stdlib.h>
#include <iostream>
class Fraction {
private:
int num, den;
public:
void set(int n, int d) {num=n; den=d; normalize();}
int get_num(){return num;}
int get_den(){return den;}
private:
void normalize();
int gcf(int a, int b);
int lcm(int a, int b);
};
void Fraction::normalize() {
if (den == 0 || num == 0) {
num = 0;
den = 1;
}
if (den < 0) {
num *= -1;
den *+ -1;
}
int n = gcf(num, den);
num = num / n;
den = den / n;
}
int Fraction::gcf(int a, int b) {
if (a % b == 0)
return abs(b);
else return gcf(b, a % b);
}
int Fraction::lcm(int a, int b) {
return(a / gcf(a, b)) * b;
}
If it helps at all, I am using GCC with the command g++ -o.
Any help much appreciated!
Where is your main function? Every "ordinary" program in C++ starts from main function, which is why the linker is looking for one. You haven't provided it. Hence the error.
I think the problem is that you're compiling a source file that doesn't contain a main function. Not every source file has to have main defined, but every C++ program needs to have it somewhere, and since you didn't post any other source files I'll assume that this is your only file. If you try compiling and linking this code, you'll get an error because there is no entry point into the program.
To fix this, either link your code together with a file that contains a main function, or add a main function to your code, or compile the code without linking it (this depends on your compiler).
Also, you should probably split your code into a .h/.cpp pair. Typically speaking, classes are defined in header files so that they can be used by other parts of the program, while implementations are left int the .cpp file so that they aren't visible to clients.
Add a -c flag when using gcc; it stops the compiler looking for the main function
Almost every C++ function has a main function, which tells the computer which part of your code it should do first. Otherwise, if someone starts your program, where should it begin? It has a form like below:
int main(int argc, char **argv) {
//what should happen when someone runs the program?
//that goes here
return 0; //program all done
}
I think u must change the extension of the file u are using to ".h" instead of ".cpp"
for example :
if this file is named as abc.cpp and u r compiling it the way "gcc abc.cpp" then u must change it to "gcc abc.h" ......
this will instruct the compiler to compile a Header rather than an object file.... :)

(C++) Linking with namespaces causes duplicate symbol error

For the past few days, I have been trying to figure out how to link the files for a CLI gaming project I have been working on. There are two halves of the project, the Client and the Server code.
The client needs two libraries I've made. The first is a general purpose game board. This is split between GameEngine.h and GameEngine.cpp. The header file looks something like this
namespace gfdGaming {
// struct sqr_size {
// Index x;
// Index y;
// };
typedef struct { Index x, y; } sqr_size;
const sqr_size sPos = {1, 1};
sqr_size sqr(Index x, Index y);
sqr_size ePos;
class board
{
// Prototypes / declarations for the class
}
}
And the CPP file is just giving everything content
#include "GameEngine.h"
type gfdGaming::board::functions
The client also has game-specific code (in this case, TicTacToe) split into declarations and definitions (TTT.h, Client.cpp). TTT.h is basically
#include "GameEngine.h"
#define TTTtar "localhost"
#define TTTport 2886
using namespace gfdGaming;
void* turnHandler(void*);
namespace nsTicTacToe
{
GFDCON gfd;
const char X = 'X';
const char O = 'O';
string MPhostname, mySID;
board TTTboard;
bool PlayerIsX = true, isMyTurn;
char Player = X, Player2 = O;
int recon(string* datHolder = NULL, bool force = false);
void initMP(bool create = false, string hn = TTTtar);
void init();
bool isTie();
int turnPlayer(Index loc, char lSym = Player);
bool checkWin(char sym = Player);
int mainloop();
int mainloopMP();
}; // NS
I made the decision to put this in a namespace to group it instead of a class because there are some parts that would not work well in OOP, and it's much easier to implement later on.
I have had trouble linking the client in the past, but this setup seems to work.
My server is also split into two files, Server.h and Server.cpp.
Server.h contains exactly:
#include "../TicTacToe/TTT.h" // Server needs a full copy of TicTacToe code
class TTTserv;
struct TTTachievement_requirement {
Index id;
Index loc;
bool inUse;
};
struct TTTachievement_t {
Index id;
bool achieved;
bool AND, inSameGame;
bool inUse;
bool (*lHandler)(TTTserv*);
char mustBeSym;
int mustBePlayer;
string name, description;
TTTachievement_requirement steps[safearray(8*8)];
};
class achievement_core_t : public GfdOogleTech {
public: // May be shifted to private
TTTachievement_t list[safearray(8*8)];
public:
achievement_core_t();
int insert(string name, string d, bool samegame, bool lAnd, int lSteps[8*8], int mbP=0, char mbS=0);
};
struct TTTplayer_t {
Index id;
bool inUse;
string ip, sessionID;
char sym;
int desc;
TTTachievement_t Ding[8*8];
};
struct TTTgame_t {
TTTplayer_t Player[safearray(2)];
TTTplayer_t Spectator;
achievement_core_t achievement_core;
Index cTurn, players;
port_t roomLoc;
bool inGame, Xused, Oused, newEvent;
};
class TTTserv : public gSserver {
TTTgame_t Game;
TTTplayer_t *cPlayer;
port_t conPort;
public:
achievement_core_t *achiev;
thread threads[8];
int parseit(string tDat, string tsIP);
Index conCount;
int parseit(string tDat, int tlUser, TTTplayer_t** retval);
private:
int parseProto(string dat, string sIP);
int parseProto(string dat, int lUser);
int cycleTurn();
void setup(port_t lPort = 0, bool complete = false);
public:
int newEvent;
TTTserv(port_t tlPort = TTTport, bool tcomplete = true);
TTTplayer_t* userDC(Index id, Index force = false);
int sendToPlayers(string dat, bool asMSG = false);
int mainLoop(volatile bool *play);
};
// Other
void* userHandler(void*);
void* handleUser(void*);
And in the CPP file I include Server.h and provide main() and the contents of all functions previously declared.
Now to the problem at hand
I am having issues when linking my server. More specifically, I get a duplicate symbol error for every variable in nsTicTacToe (and possibly in gfdGaming as well). Since I need the TicTacToe functions, I link Client.cpp ( without main() ) when building the server
ld: duplicate symbol nsTicTacToe::PlayerIsX in Client.o and Server.o
collect2: ld returned 1 exit status
Command /Developer/usr/bin/g++-4.2 failed with exit code 1
It stops once a problem is encountered, but if PlayerIsX is removed / changed temporarily than another variable causes an error
Essentially, I am looking for any advice on how to better organize my code to hopefully fix these errors.
Disclaimers:
-I apologize in advance if I provided too much or too little information, as it is my first time posting
-I have tried using static and extern to fix these problems, but apparently those are not what I need
Thank you to anyone who takes the time to read all of this and respond =)
You get error about duplicate definitions because that's what you have: each time a .cpp file includes TTT.h, a global bool PlayerIsX is defined (in the nsTicTacToe namespace, but still global). In this case, it's Server.cpp and Client.cpp that are including it.
One way to solve this could be to change the definitions into declarations by using extern, then doing the actual definition in a corresponding .cpp file (TTT.cpp, for instance).
In TTT.h:
namespace nsTicTacToe {
...
extern bool PlayerIsX;
...
}
In TTT.cpp:
#include "TTT.h"
bool nsTicTacToe::PlayerIsX;
and so on for the other definitions.
By the way, remember to have proper guard #ifdefs:
#ifndef __TTT_H
#define __TTT_H
... header contents
#endif // __TTT_H
Actually, extern IS what you need. You're probably just not realizing or remembering that you'll also have to define such variables in a cpp file.
header:
extern int somevar;
source:
int somevar = ?;
By putting all of your globals in the header you're making copies of them everywhere you include them, which is exactly what your compiler is bitching about.
You are essentially using globals, which is strongly not recommended in C++, but is sometimes necessary in C.
You could get it working with extern, but the "better" answer would be to wrap your globals in a state object of some sort.
struct State
{
GFDCON gfd;
const char X;
const char O;
string MPhostname, mySID;
board TTTboard;
bool PlayerIsX, isMyTurn;
char Player, Player2;
};
Create your state object in Main and pass it to each function that needs to know the state of the game system.
This will lead to much better code organization in the long run.
you could put the namespace nsTicTacToe part into it's own .cpp file, compile it separately and link it in.
You might also need a header file which just declares externs for the variables, and include that in you client and server .cpp files.