Linker Error C++ "undefined reference " [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is an undefined reference/unresolved external symbol error and how do I fix it?
Trying to compile my program via g++ -o prog1 main.cpp -std=c++0x
I get the error:
/tmp/cc1pZ8OM.o: In function `main':
main.cpp:(.text+0x148): undefined reference to `Hash::insert(int, char)'
collect2: error: ld returned 1 exit status
main.cpp
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <functional>
#include "Hash.h"
using namespace std;
int main(int argc, char *argv[]) {
//preset prime number
int prime = 101;
hash<char> h1;
int key;
Hash HashTable;
// check for Request & string parameters
if(argc != 3) {
cout << "Run program with 2 parameters. [Lower Case]" << endl;
cout << "[1] insert, find, or delete" << endl;
cout << "[2] string" << endl;
}
if(strcmp(argv[1], "insert") == 0) {
//Get Hash for argv[2] aka value
key = h1(*argv[2]);
//check 1
cout << "Hash: " << key << endl;
key = key % prime;
//check 2
cout << "Mod 101 Hash: " << key << endl;
HashTable.insert(key, *argv[2]); //PROBLEM here
}
return 0;
}
Hash.h file:
#include <iostream>
#include <cstring>
#include "LinkedList.h"
using namespace std;
class Hash {
//100 slot array for hash function
LinkedList *hashFN[100];
public:
void insert(int key, char value);
//void deleteItem(int key);
//char* find(int key);
};
Any ideas? Using this to build a hash table with set size.
Edit: Hash.cpp file
#include <iostream>
#include <cstring>
#include "Hash.h"
using namespace std;
void Hash::insert(int key, char value){
*hashFN[key]->addFront(value);
cout << "Success!" << endl;
}
Trying to compile via terminal now with:
g++ -c Hash.cpp -o Hash.o
g++ -o prog1 main.cpp Hash.o -std=c++0x
It goes into an infinite loop somehow.

Your header file Hash.h declares "what class hash should look like", but not its implementation, which is (presumably) in some other source file we'll call Hash.cpp. By including the header in your main file, the compiler is informed of the description of class Hash when compiling the file, but not how class Hash actually works. When the linker tries to create the entire program, it then complains that the implementation (toHash::insert(int, char)) cannot be found.
The solution is to link all the files together when creating the actual program binary. When using the g++ frontend, you can do this by specifying all the source files together on the command line. For example:
g++ -o main Hash.cpp main.cpp
will create the main program called "main".

This error tells you everything:
undefined reference toHash::insert(int, char)
You're not linking with the implementations of functions defined in Hash.h. Don't you have a Hash.cpp to also compile and link?

Your error shows you are not compiling file with the definition of the insert function. Update your command to include the file which contains the definition of that function and it should work.

Related

Issue with compiling and running c++ program on scite

So I'm just writing a simple c++ program and I am having some issues running the program. I could build my make file but when I try to run the testfile it gives me an "collect2.exe: error: ld returned 1 exit status" error, "undefined reference to Account::Account(int, double, double)" and basically all of my methods. I've attached a picture of my .h file, and .cpp below.
.h File
.cpp file
And the test file is like this :
#include <iostream>
#include <string>
#include <iomanip>
#include "Account.h"
using namespace std;
int main(){
Account account1(1122, 20000, 4.5);
account1.withdraw(2500);
account1.deposit(3000);
cout<<"Account Information"<<endl
<<"ID: " << account1.getID()<<endl
<<"Balance: " << account1.getBalance()<<endl
<<"Monthly Interest Rate: " << account1.getMonthlyInterestRate()<< endl;
return 0;
}
Make file:
TestAccount: TestAccount.o Account.o
g++ TestAccount.o Account.o -o TestAccount
TestAccount.o: TestAccount.cpp Account.h
g++ -c TestAccount.cpp
Account.o: Account.cpp Account.h
g++ -c Account.cpp

simple c++ code does not compile (linker command failed with exit code 1)

I'm new to C++ and studying the Dietel book. On the book, it has some example codes for classes and interfaces
Gradebook.h
#ifndef GradeBook_h
#define GradeBook_h
#endif /* GradeBook_h */
#include <string>
class GradeBook
{
public:
explicit GradeBook( std::string );
void setCourseName( std::string );
std::string getCourseName() const;
void displayMessage() const;
private:
std::string courseName;
};
Gradebook.cpp
#include <iostream>
#include "GradeBook.h"
using namespace std;
GradeBook::GradeBook( string name )
{
courseName = name;
}
void GradeBook::setCourseName( string name )
{
courseName = name;
}
string GradeBook::getCourseName() const
{
return courseName;
}
void GradeBook::displayMessage() const
{
std::cout << "Welcome to the grade book for " << getCourseName() << std::endl;
}
main.cpp
#include <iostream>
#include "GradeBook.h"
using namespace std;
int main()
{
GradeBook gradeBook1("CS 101 Introduction to C++ Programming");
GradeBook gradeBook2("CS 102 Data Structures in C++");
cout << "gradeBook1 : " << gradeBook1.getCourseName() << endl;
cout << "gradeBook2 : " << gradeBook2.getCourseName() << endl;
}
So, I am trying to compile this on my mac terminal using g++ main.cpp -o example.out. But it seems that this constantly gives me an error saying that
Undefined symbols for architecture x86_64:
"GradeBook::GradeBook(std::__1::basic_string, std::__1::allocator >)", referenced from:
_main in main-0602c7.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I have tried getting rid of most of the function declarations and function implementations except for the constructor and the member variable, but it seems to be giving me the same error still.
I think I copied the code exactly from the book, but I do not understand what I am doing wrong. Any help would be appreciated.
You'll have to compile all sources, so add your GradeBook class implementation too
g++ main.cpp GradeBook.cpp -o example.out
~~~~~~~~~~~~~
As already mentioned in above example, you have to mention both source files (main.cpp and GradeBook.cpp) while compiling the code.
This will work.
However, there is one more potential problem in your code.
#ifndef GradeBook_h
#define GradeBook_h
#endif /* GradeBook_h */
There is no code inside ifndef-endif guard. You need to put the complete code in .h file inside ifndef-endif. Otherwise when you work on a larger project and GradeBook.h is getting included from multiple places, you might get redeclaration error.

error: uint64_t was not declared in this scope when compiling C++ program

I am trying out a simple program to print the timestamp value of steady_clock as shown below:
#include <iostream>
#include <chrono>
using namespace std;
int main ()
{
cout << "Hello World! ";
uint64_t now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
cout<<"Value: " << now << endl;
return 0;
}
But whenever I am compiling like this g++ -o abc abc.cpp, I am always getting an error:
In file included from /usr/include/c++/4.6/chrono:35:0,
from abc.cpp:2:
/usr/include/c++/4.6/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.
abc.cpp: In function âint main()â:
abc.cpp:7:3: error: âuint64_tâ was not declared in this scope
abc.cpp:7:12: error: expected â;â before ânowâ
abc.cpp:8:22: error: ânowâ was not declared in this scope
Is there anything wrong I am doing?
Obviously, I'm not following certain best practices, but just trying to get things working for you
#include <iostream>
#include <chrono>
#include <cstdint> // include this header for uint64_t
using namespace std;
int main ()
{
{
using namespace std::chrono; // make symbols under std::chrono visible inside this code block
cout << "Hello World! ";
uint64_t now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
cout<<"Value: " << now << endl;
}
return 0;
}
and then compile using C++11 enabled (c++0x in your case)
g++ -std=c++0x -o abc abc.cpp
You should include stdint.h file.
If you really want to include, add "#define __STDC_LIMIT_MACROS"
Ref: https://stackoverflow.com/a/3233069/6728794

Error when trying to separating class into .h, .cpp

This is a minimal program that I made to understand this problem better.
ADT.h
#ifndef ADT_H
#define ADT_H
class ADT {
public:
void print();
};
#endif
ADT.cpp
#include <iostream>
#include "ADT.h"
using namespace std;
void ADT::print()
{
cout << "This program works." << endl;
}
testADT.cpp
#include <iostream>
#include "ADT.h"
using namespace std;
int main(void)
{
ADT sa;
sa.print();
return 0;
}
I compiled it with the vim/minGW compiler my school provided me like so:
g++ testADT.cpp
Which produced the following error:
C:\Users\King\AppData\Local\Tempcc6eoWAP.o:testADT.cpp(.text+0x15 reference to 'ADT::print()'
collect2.exe error: ld returned 1 exit status
Can you explain this error message and indicate the error in my code?
You didn't post the error, but I see that you're missing the semicolon after void print()in the header.
EDIT: That's a linker error. Each source file should be compiled into an object file; then the object files linked:
g++ -c -oADT.o ADT.cpp
g++ -c -otestADT.o testADT.cpp
g++ -oADT ADT.o testADT.o
You can also do it in one line as in michaeltang's answer, but then you can't recompile the sources individually (the 2 step method scales better).
You should also compile ADT.cpp
g++ -o testadt testADT.cpp ADT.cpp

dlopen() gives unresolved symbol error when .so tries to use a class from the main executable. Why?

I'm on Linux, the question is concerning shared objects of C++ classes.
The problem comes when my shared objects try to use resources linked into the main executable. I have the following codes:
loader.cpp:
#include <dlfcn.h>
#include <iostream>
#include "CommonInfo.h"
using namespace std;
int main(int argc, char** argv) {
for(int i=1; i<argc; ++i) {
string pth = "./";
pth.append(argv[i]);
void* dh = dlopen(pth.c_str(), RTLD_NOW);
if(dh==NULL) {
cerr << dlerror() << endl;
return 1;
}
CommonInfo::GetInfoFunc getInfo = (CommonInfo::GetInfoFunc)(dlsym(dh,"getInfo"));
if(getInfo==NULL) {
cerr << dlerror() << endl;
return 1;
}
CommonInfo* info = getInfo();
cout << "INFO: " << info->getX() << endl;
delete info;
}
return 0;
}
CommonInfo.h:
#include <string>
class CommonInfo {
public:
typedef CommonInfo* (*GetInfoFunc)();
private:
std::string x;
public:
CommonInfo(const std::string& nx);
std::string getX() const;
};
EDIT:
I accidentaly forgot to ctrl-c + ctrl-v the source of CommonInfo.cpp here. Of course, it is there during compilation, so CommonInfo.cpp:
#include "CommonInfo.h"
CommonInfo::CommonInfo(const std::string& nx) : x(nx) {
}
std::string CommonInfo::getX() const {
return x;
}
A Plugin.h header:
#include "CommonInfo.h"
extern "C" CommonInfo* getInfo();
A very simple Plugin.cpp:
#include <iostream>
#include "Plugin.h"
#include "CommonInfo.h"
using namespace std;
CommonInfo* getInfo() {
return new CommonInfo("I'm a cat!");
}
Compiling is done with:
g++ -rdynamic -ldl -Werror CommonInfo.cpp loader.cpp -o loader
g++ -shared -fPIC -Werror Plugin.cpp -o Plugin.so
Running:
./loader Plugin.so
And there goes the error:
./loader: symbol lookup error: ./Plugin.so: undefined symbol: _ZN10CommonInfoC1ERKSs
Indeed, looking inside Plugin.so with nm Plugin.so | grep -i CommonInfo it gives an 'U' for this symbol (unresolved), which is perfectly ok.
Also, looking inside the binary of loader with nm loader.so | grep -i CommonInfo I could find the symbol with 'T', which is also ok.
Question is, shouldn't dlfcn.h unresolve the symbol in question from the main binary? Without this feature it becomes quite hard to use these stuff... Do I have to write a class factory function for CommonInfo, load it with dlfcn from the plugin and call that?
Thanks in advance,
Dennis
I haven't looked closely at your code, but I have in the past found behavior like you describe in the title when I did not link the executable with -E. (Or -Wl,-E when linking with gcc rather than ld.)
Note that not all platforms let the shared libraries take symbols from the calling binary. Linux and the *BSDs allow you to. But if you ever want to port to, say, Windows, you will not be able to use this pattern. I believe there are also some Unix-type OS's that won't let you do this. (It's been a while so I don't remember... Maybe it was Solaris?)