Undefined Symbols for architecture x86_64: Compiling problems
There's no mystery here, the linker is telling you that you haven't defined the missing symbols, and you haven't.
Similarity::Similarity()
or Similarity::~Similarity()
are just missing and you have defined the others incorrectly,
void Similarity::readData(Scanner& inStream){
}
not
void readData(Scanner& inStream){
}
etc. etc.
The second one is a function called readData, only the first is the readData method of the Similarity class.
To be clear about this, in Similarity.h
void readData(Scanner& inStream);
but in Similarity.cpp
void Similarity::readData(Scanner& inStream){
}
Trevor Hutto
Updated on October 27, 2020Comments
-
Trevor Hutto over 3 years
So I am trying to start an assignment, my professor gives us a Main.cpp, Main.h, Scanner.cpp, Scanner.h, and some other utilities.
My job is to create a Similarity class to compare documents using the cosine and Jaccard coefficients. However, I can not seem to get the project linked correctly, therefore I am unable to start on the actual code.
After trying for several hours to see what I am doing wrong, I need fresh eyes to see what I am doing wrong, I suspect it is obvious.
Here is the Main.cpp
#include "Main.h" using namespace std; static const string TAG = "Main: "; int main(int argc, char *argv[]) { string inStreamName; string logStreamName; string outStreamName; ofstream outStream; string timeCallOutput; Scanner inStream; Similarity similarity; /////////////////////////////////////////////////////////////// // Boilerplate for naming files and opening files Utils::CheckArgs(3, argc, argv, "infilename outfilename logfilename"); outStreamName = static_cast<string>(argv[2]); logStreamName = static_cast<string>(argv[3]); Utils::FileOpen(outStream, outStreamName); Utils::LogFileOpen(logStreamName); timeCallOutput = Utils::timecall("beginning"); Utils::logStream << timeCallOutput << endl; Utils::logStream << TAG << "Beginning execution" << endl; Utils::logStream << TAG << "outfile '" << outStreamName << "'" << endl; Utils::logStream << TAG << "logfile '" << logStreamName << "'" << endl; Utils::logStream.flush(); /////////////////////////////////////////////////////////////// // What follows here is the real work of this code. // read the entire input file and echo it back // compute the two similarity coefficients inStreamName = static_cast<string>(argv[1]); inStream.openFile(inStreamName); Utils::logStream << TAG << "infile '" << inStreamName << "'" << endl; Utils::logStream.flush(); similarity.readData(inStream); outStream << TAG << "Data Begin\n" << similarity.toString() << endl; outStream << TAG << "Data End\n" << endl; outStream.flush(); inStream.close(); outStream << TAG << "Begin similarity computation" << endl; outStream << TAG << "Maximum Jaccard similarity:\n" << similarity.maxJaccard() << endl; outStream << TAG << "Maximum cosine similarity:\n" << similarity.maxCosine() << endl; outStream << TAG << "End similarity computation" << endl; outStream.flush(); /////////////////////////////////////////////////////////////// // Boilerplate for terminating gracefully Utils::logStream << TAG << "Ending execution" << endl; timeCallOutput = Utils::timecall("ending"); Utils::logStream << timeCallOutput << endl; Utils::logStream.flush(); outStream.flush(); Utils::FileClose(outStream); Utils::FileClose(Utils::logStream); return 0; }
And the Main.h
#ifndef MAIN_H #define MAIN_H #include "../../Utilities/Utils.h" #include "../../Utilities/Scanner.h" #include "Similarity.h" class Main { public: int main(); virtual ~Main(); private: }; #endif // MAIN_H
My Similarity.cpp
#include "Similarity.h" using namespace std; void readData(Scanner& inStream){ } string maxCosine(){ return "cosine"; } string maxJaccard(){ return "jaccard"; } string toString(){ return "toString"; }
And finally my Similarity.h:
#ifndef SIMILARITY_H #define SIMILARITY_H #include "../../Utilities/Scanner.h" class Similarity { public: Similarity(); virtual ~Similarity(); void readData(Scanner& inStream); string maxCosine(); string maxJaccard(); string toString(); private: }; #endif
When I use the makefile he provided, and the one I have to use in order for his script to work to grade it I get this error:
g++ -O3 -Wall -o Similarity.o -c Similarity.cpp g++ -O3 -Wall -o Aprog Main.o Similarity.o Scanner.o ScanLine.o Utils.o Undefined symbols for architecture x86_64: "Similarity::maxJaccard()", referenced from: _main in Main.o "Similarity::readData(Scanner&)", referenced from: _main in Main.o "Similarity::toString()", referenced from: _main in Main.o "Similarity::maxCosine()", referenced from: _main in Main.o "Similarity::Similarity()", referenced from: _main in Main.o "Similarity::~Similarity()", referenced from: _main in Main.o ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status make: *** [Aprog] Error 1
Thank you for reading through all that, any suggestions or solutions would be greatly appreciated.
-
Trevor Hutto almost 11 yearsWhen I do that, I get an extra qualification on member 'Similarity'. Any thoughts there?
-
john almost 11 yearsCould you quote the exact error message and the code it refers to?
-
Trevor Hutto almost 11 yearsIn file included from Similarity.cpp:1: Similarity.h:12: error: extra qualification ‘Similarity::’ on member ‘readData’ is the error message.
-
john almost 11 yearsYou put
Similarity::readData
in the .cpp file not in the .h file. See edit to the answer. -
Trevor Hutto almost 11 yearsvoid Similarity::readData(Scanner& inStream); string Similarity::maxCosine(); string Similarity::maxJaccard(); string Similarity::toString(); -----These are the lines it is referring to.
-
john almost 11 years@TrevorHutto You've made the wrong edit, your .h file is correct, your .cpp file is wrong.
-
Trevor Hutto almost 11 yearsOk, to be clear, in the .h file I have 'Similarity();' and 'virtual ~Similarity();' and in the .cpp I have 'Similarity::Similarity();' and 'Similarity::~Similarity();'
-
john almost 11 yearsNot quite, in the .h file you have
Similarity();
andvirtual ~Similarity();
, these are declarations but in the .cpp file you should have definitionsSimilarity::Similarity() { ... }
andSimilarity::~Similarity() { ... }
(you fill in the ...). -
Trevor Hutto almost 11 yearsThank you, it compiled. One question, what is the purpose of the Similarity:: before the definition of constructors and functions? What does it do?
-
john almost 11 yearsIf you write in your .cpp file
string maxCosine() { ...
then the compiler doesn't know that has anything to do with the Similarity class. You saystring Similarity::maxCosine() { ...
to tell the compiler that you are talking about the maxCosine function in the Similarity class, rather than some random function that just happens to have the same name. But in the .h filestring maxCosine();
is insideclass Similarity { ... }
so the compiler knows that you are declaring a function of the Similarity class.