Missing Vtable when linking .o files - c++

I am writing a simple server program using ICE by ZeroC. When I try to link the .o files it gave me the following error message:
$ c++ -o server UserMap.o Server.o -L/Library/Developer/Ice-3.5.0/lib -lIce -lIceUtil
Undefined symbols for architecture x86_64:
"VTT for UserMapI", referenced from:
UserMapI::UserMapI() in Server.o
"vtable for UserMapI", referenced from:
UserMapI::UserMapI() in Server.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
After some googling I understand that the problem is I have an abstract class with 3 virtual methods declared in UserMap.ice (and hence in UserMap.h and UserMap.cpp generated by the command slice2cpp UserMap.ice), and in Server.cpp I have a class called UserMapI:public UserMap which implements the three virtual methods and another private helper function. The error is generated because the compiler thinks I have declared all functions(methods) in UserMap.h and UserMap.cpp.
My understanding to this problem is that I should modify the link command so that the linker will know that there are more functions in UserMapI declared in Server.cpp, but I don't have enough knowledge to do the modification. Can someone help me please?
Thank you all.
Here is the compiler command I am using to get Server.o and UserMap.o:
c++ -I. -I/Library/Developer/Ice-3.5.0/include -c UserMap.cpp Server.cpp
Here's the code of UserMap.ice:
module DR
{
class UserMap
{
void addUserToLocation(int userID, int x, int y);
string getUsersNearLocation(int x, int y, int distance);
void removeFromMap(int userID, int x, int y);
};
};
slice2cpp command slices this .ice file into a .h and a .cpp file that works as an API between server and client.
In Server.cpp I have the following include:
#include <Ice/Ice.h>
#include "UserMap.h"
#include <map>
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
and the following subclass:
class UserMapI : public UserMap
{
public:
virtual void addUserToLocation(int userID, int x, int y, const Ice::Current &);
virtual string getUsersNearLocation(int x, int y, int distance, const Ice::Current &);
virtual void removeFromMap(int userID, int x, int y, const Ice::Current &);
private:
string stringify(int x, int y);
};
And after implementing all methods here's the main function:
int main(int argc, char* argv[])
{
int status = 0;
Ice::CommunicatorPtr ic;
try {
ic = Ice::initialize(argc, argv);
Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithEndpoints("SimpleUserMapAdapter", "default -p 10000");
Ice::ObjectPtr object = new UserMapI;
adapter->add(object, ic->stringToIdentity("SimpleUserMap"));
adapter->activate();
ic->waitForShutdown();
} catch (const Ice::Exception & e) {
cerr << e << endl;
status = 1;
} catch (const char * msg) {
cerr << msg << endl;
status = 1;
}
if (ic){
try {
ic->destroy();
} catch (const Ice::Exception & e) {
cerr << e << endl;
status = 1;
}
}
return status;
}
Here's the UserMap.h.

Related

g++ ld: symbol(s) not found for architecture x86_64 - without more specific error message

I've been trying to solve this problem for hours and hours...
I have a header file, implementation file and a driver file.
HEADER:
class PhoneNumber
{
private:
const int MAXTEXTS;
static int live;
static int text; // number of total texts from all the phones.
string areaCode;
string exchange;
string line;
int nlive;
int ntext; // number of texts sent on this phone
public:
static int MaxPhones;
PhoneNumber();
PhoneNumber(string, string, string, int);
void inputPhoneNumber();
void displayPhoneNumber();
void sendText();
void dialNum();
int getLive();
int getText();
int getnLive();
int getnText();
static void addLive()
{
live++;
}
static void addText()
{
text++;
}
};
IMPLEMENTATION:
int PhoneNumber::getnLive()
{
return nlive;
}
int PhoneNumber::getnText()
{
return ntext;
}
int PhoneNumber::getLive()
{
return live;
}
int PhoneNumber::getText()
{
return text;
}
error message:
habins-mbp:CS2000 Habin$ g++ -o PhoneNumber PhoneNumber.cpp PhoneNumberDriver.cpp
Undefined symbols for architecture x86_64:
"PhoneNumber::live", referenced from:
PhoneNumber::getLive() in PhoneNumber-f64d4d.o
PhoneNumber::addLive() in PhoneNumber-f64d4d.o
"PhoneNumber::text", referenced from:
PhoneNumber::getText() in PhoneNumber-f64d4d.o
PhoneNumber::addText() in PhoneNumber-f64d4d.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
IF I use g++ -c, it compiles meaning that the code works. It seems like the static int live is giving me so much trouble.
Been trying to solve this for 10+ hours and to no avail. I'm about to snap my computer in half!
please help me
You should define all the static member variables in IMPLEMENTATION part.
int PhoneNumber::live;
int PhoneNumber::text;
int PhoneNumber::MaxPhones;

Undefined symbol: Symbol referencing errors. No output written to main

Have the following program:
#include <iostream>
#include <string>
using namespace std;
class Record
{
public:
static Record* GetInstance(string name);
void printName();
private:
Record(string name);
string name_;
static Record *record;
};
Record::Record(string name)
:name_(name)
{
}
Record*
Record::GetInstance(string name)
{
if(record == NULL) {
record = new Record(name);
}
return record;
}
void
Record::printName()
{
cout << name_ << endl;
}
int main()
{
Record* record1 = Record::GetInstance("sellers");
record1->printName();
Record* record2 = Record::GetInstance("customers");
record2->printName();
}
I am compiling and linking with:
g++ -g -c -Wall main.cpp
g++ -g -Wall main.o -o main
The compilation completes without error(1st command). But the linking is giving this error:
Undefined first referenced
symbol in file
Record::record main.o
ld: fatal: Symbol referencing errors. No output written to main
collect2: ld returned 1 exit status
Wondering how to correct this.
You need to define the variable somewhere, i.e.
Record *Record::record;

c++ compile error Undefined symbols for architecture x86_64

I wrote a class named UserScore:
//header
using namespace std;
class UserScore{
public:
UserScore(const int &user_id, const int &rating);
private:
int _user_id;
int _rating;
};
//cpp
#include "UserScore.h"
UserScore::UserScore (const int &user_id, const int &rating):
_user_id(user_id),
_rating(rating)
{
}
The compile command is:
g++ src/UserScore.cpp -o obj/UserScore.o
But why this simple thing won't compile?
The error is:
Undefined symbols for architecture x86_64:
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
You need to include the -c option to the compilation line if you want to generate an object file, otherwise the compiler assumes you are trying to build an executable and will complain if you don't have a main() method (which is happening here).
To make an object file which you will link later to a code file that has a "main()" method in it you need to use
g++ -c src/UserScore.cpp -o obj/UserScore.o
Which is what I think you are trying to do.
Alternatively you just need to add a main function to your code and then you can make an executable.
//header
using namespace std;
class UserScore{
public:
UserScore(const int &user_id, const int &rating);
private:
int _user_id;
int _rating;
};
//cpp
#include "UserScore.h"
UserScore::UserScore (const int &user_id, const int &rating):
_user_id(user_id),
_rating(rating)
{
}
int main()
{
return 0;
}

Linking error for a naive singleton class in C++

My code is:
class cMySingleton{
private:
static bool bInstantiated;
int mInt;
cMySingleton(){
mInt=0;
}
public:
cMySingleton(int c){
if (bInstantiated){
cout << "you can only instantiated once";
}
else {
cMySingleton();
mInt=c;
}
}
};
int main () {
cMySingleton s(5);
cMySingleton t(6);
}
The linker keeps complaining:
Undefined symbols for architecture x86_64:
"cMySingleton::bInstantiated", referenced from:
cMySingleton::cMySingleton(int) in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
What is going on? C++ novice here~~
you should initialize static field.
http://ideone.com/Y1huV
#include <iostream>
class cMySingleton{
private:
static bool bInstantiated;
int mInt;
cMySingleton(){
mInt=0;
}
public:
cMySingleton(int c){
if (bInstantiated){
std::cout << "you can only instantiated once";
}
else {
cMySingleton();
mInt=c;
}
}
};
bool cMySingleton::bInstantiated = true;
int main () {
cMySingleton s(5);
cMySingleton t(6);
}
More information you can be find here:
Static Data Member Initialization
there was also missing include and std:: around cout.
Initialize
static bool bInstantiated;
outside of cMySingleton
bool CMySingleton::bInstantiated;
Dont forget to initialize your static member outside of your class declaration in .cpp file:
bool cMySingleton::bInstantiated = false;

ld symbol not found

Looked around and found a few similar questions but none of them were the same. Most had to do with the constructor or destructor. This issue is, more than likely, a result of my rusty C++ linker memory (picking it back up after a few years).
I'll keep it real simple since this is probably a basic misunderstanding of the linker:
data.h
#pragma once
namespace test {
class Data_V1 {
public:
// some getters/setters
int getData() { return _d; }
void setData( int d ) { _d = d; }
private:
// some data
int _d;
};
}
builder.h
#pragma once
namespace test {
template <class V>
class Builder {
public:
void build();
};
}
builder.cpp
#include <iostream>
#include "builder.h"
namespace test {
template<class V>
void Builder<V>::build() {
std::cout << "Insert building logic" << std::endl;
}
}
main.cpp
#include "builder.h"
#include "data.h"
using namespace test;
int main(int argc, char* argv[]) {
Builder<Data_V1> b;
b.build();
}
compiling:
g++ -Wall -ansi -pedantic -c builder.cpp
g++ -Wall -ansi -pedantic -c main.cpp
g++ -Wall -ansi -pedantic -o main main.o builder.o
Link error:
Undefined symbols for architecture x86_64:
"test::Builder<test::Data_V1>::build()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
Any help would be appreciated!
Template definitions need to be visible to all translation units. Move the definition from the cpp to the header.
Builder.h
#pragma once
namespace test {
template <class V>
class Builder {
public:
void build();
};
template<class V>
void Builder<V>::build() {
std::cout << "Insert building logic" << std::endl;
}
}
Before you ask, no, there's no way to hide the implementation unless you know all possible specializations beforehand.
Templates represent a generalized form for the creation of a new class. If the implementation is not visible, when you attempt to specialize the template, the compiler can't know what code to generate.