Undefined Symbols for architecture x86_64: Compiling problems

237,967

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){
}
Share:
237,967
Trevor Hutto
Author by

Trevor Hutto

Updated on October 27, 2020

Comments

  • Trevor Hutto
    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
    Trevor Hutto almost 11 years
    When I do that, I get an extra qualification on member 'Similarity'. Any thoughts there?
  • john
    john almost 11 years
    Could you quote the exact error message and the code it refers to?
  • Trevor Hutto
    Trevor Hutto almost 11 years
    In file included from Similarity.cpp:1: Similarity.h:12: error: extra qualification ‘Similarity::’ on member ‘readData’ is the error message.
  • john
    john almost 11 years
    You put Similarity::readData in the .cpp file not in the .h file. See edit to the answer.
  • Trevor Hutto
    Trevor Hutto almost 11 years
    void Similarity::readData(Scanner& inStream); string Similarity::maxCosine(); string Similarity::maxJaccard(); string Similarity::toString(); -----These are the lines it is referring to.
  • john
    john almost 11 years
    @TrevorHutto You've made the wrong edit, your .h file is correct, your .cpp file is wrong.
  • Trevor Hutto
    Trevor Hutto almost 11 years
    Ok, 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
    john almost 11 years
    Not quite, in the .h file you have Similarity(); and virtual ~Similarity();, these are declarations but in the .cpp file you should have definitions Similarity::Similarity() { ... } and Similarity::~Similarity() { ... } (you fill in the ...).
  • Trevor Hutto
    Trevor Hutto almost 11 years
    Thank you, it compiled. One question, what is the purpose of the Similarity:: before the definition of constructors and functions? What does it do?
  • john
    john almost 11 years
    If you write in your .cpp file string maxCosine() { ... then the compiler doesn't know that has anything to do with the Similarity class. You say string 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 file string maxCosine(); is inside class Similarity { ... } so the compiler knows that you are declaring a function of the Similarity class.