c++ compile error Undefined symbols for architecture x86_64 - c++

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;
}

Related

c++ undefined reference to member function defined outside of header file

I am under the impression that you are allowed to define member functions of a class in one file and then use those functions in another file, as long as both files are compiled and sent to the linker. However, doing this gives me an undefined reference error if I use g++ (4.6.4). Interestingly, using the intel compiler (icpc 11.0) does not give an error and everything works. Is there some flag I can set in g++ to make this work, or is the intel compiler letting me get away with something I shouldn't be doing? Here is some code that reproduces my problem:
class.h:
#ifndef _H
#define _H
typedef class
{
public:
int a;
int b;
void set(int x, int y);
int add(void);
} Test;
#endif
class.cpp:
#include "class.h"
void Test::set(int x, int y)
{
a = x;
b = y;
}
int Test::add(void)
{
return a+b;
}
main.cpp:
#include <cstdio>
#include "class.h"
int main(void)
{
Test n;
n.set(3, 4);
printf("%d\n", n.add());
return 0;
}
To compile, I do:
$ g++ class.cpp main.cpp -o test
/tmp/ccRxOI40.o: In function `main':
main.cpp:(.text+0x1a): undefined reference to `Test::set(int, int)'
main.cpp:(.text+0x26): undefined reference to `Test::add()'
collect2: ld returned 1 exit status
Okay, this is strange, but what happened is that this construct:
typedef class
{
public:
int a;
int b;
void set(int x, int y);
int add(void);
} Test;
while legal is not being treated semantically the same by the compiler as:
class Test
{
public:
int a;
int b;
void set(int x, int y);
int add(void);
};
The typedef version makes your methods static to the file, as indicated in the nm output:
$ nm class.o
0000000000000024 t _ZN4Test3addEv
0000000000000000 t _ZN4Test3setEii
U __gxx_personality_v0
While the class Test version makes them proper methods:
$ nm class2.o
0000000000000024 T _ZN4Test3addEv
0000000000000000 T _ZN4Test3setEii
U __gxx_personality_v0
This is why the linker failed to find the symbols.
Edit: As to why this is happening, it seems to be due to an issue with interpreting how the Standard specifies the treatment of the typedef name as a class-name. Newer compilers do not seem to exhibit the same issue. The problem reported in this question was reproduced with g++ 4.4.7.
If you move the code in your class.cpp file into main.cpp and only compile main.cpp, things will work. Alternatively, you can inline the method definitions into class.h.
If you want to leave them as separate translation units, you need to change the class.h file so that your class is defined using the class Test way instead of using the typedef on the anonymous class.

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;

Missing Vtable when linking .o files

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.

Undefined symbols for architecture x86_64: party::getArrival()

I have a header file for the party class called party.h:
#ifndef party_h
#define party_h
#include <iostream>
class party{
private:
int people;
int waitTime;
bool waiting;
int arrival;
public:
party();
party(int, int);
int getPeople();
void setPeople(int);
bool isWaiting();
void setWaiting(bool);
void setWaitTime(int);
int getwaitTime();
void setArrival(int);
int getArrival();
int getTotalTime(int);
void decrement();
};
#endif
And its implementation in party.cpp:
#include "party.h"
party::party(){}
party::party(int numPeople, int a){
people = numPeople;
arrival = a;
}
int party::getPeople(){
return people;
}
void party::setPeople(int p){
people = p;
}
bool party::isWaiting(){
return waiting;
}
void party::setWaiting(bool w){
waiting = w;
}
void party::setWaitTime(int t){
waitTime = t;
}
int party::getwaitTime(){
return waitTime;
}
void party::setArrival(int a){
arrival =a;
}
int party::getTotalTime(int current){
return (current-arrival);
}
Whenever I build the project I get the error message below,
Ld /Users/shade/Library/Developer/Xcode/DerivedData/ResSim-fvkhqxhiupiizxgffxqgoxgolsmv/Build/Products/Debug/ResSim normal x86_64 cd /Users/shade/Dropbox/School/Gwinnett_Tech/CIST_2362/final/ResSim setenv MACOSX_DEPLOYMENT_TARGET 10.8 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk -L/Users/shade/Library/Developer/Xcode/DerivedData/ResSim-fvkhqxhiupiizxgffxqgoxgolsmv/Build/Products/Debug -F/Users/shade/Library/Developer/Xcode/DerivedData/ResSim-fvkhqxhiupiizxgffxqgoxgolsmv/Build/Products/Debug -filelist /Users/shade/Library/Developer/Xcode/DerivedData/ResSim-fvkhqxhiupiizxgffxqgoxgolsmv/Build/Intermediates/ResSim.build/Debug/ResSim.build/Objects-normal/x86_64/ResSim.LinkFileList -mmacosx-version-min=10.8 -stdlib=libstdc++ -o /Users/shade/Library/Developer/Xcode/DerivedData/ResSim-fvkhqxhiupiizxgffxqgoxgolsmv/Build/Products/Debug/ResSim
Undefined symbols for architecture x86_64: "party::getArrival()", referenced from: restaurant::startSim() in restaurant.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
"party::getArrival()", referenced from: Restaurant::startSim() in restaurant.o Symbol(s) not found for architecture x86_64 Linker command failed with exit code 1 (use -v to see invocation)
This is a new error message since it was working earlier today/this weekend in visual studio. But I've changed a decent amount of code since then, the code in the gist has been updated and is what I'm working with. I'm currently trying to get it to build in xcode so I can finish debugging/programming my project that is due tonight. Any help is greatly appreciated! Thanks!
You do not define getArrival in your party.cpp file. You probably want:
int party::getArrival(){
return arrival;
}

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.