Home > Mobile >  C Error: ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with e
C Error: ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with e

Time:12-20

I'm writting a small project. I declare a class in the .hpp file and define it in a .cpp file, but when I use it, there is something error about linking.

DSMgr.hpp

#ifndef __DSMGR_HPP__
#define __DSMGR_HPP__

#include "predefine.hpp"
#include <fstream>
#include <string>

class DSMgr{
public:
    DSMgr();
    int OpenFile(std::string filename);                     // open the file speciafied by the filename 
                                                            // and return an error code
    int CloseFile();                                        // close the current file
    bFrame ReadPage(const int& page_id);                    // gain data and return what it reads
    int WritePage(const int& page_id, bFrame frm);          // called when a page is taken out of buf
                                                            // return the number of bytes that be written
    int Seek(const int& offset, const int& pos);            // move the file pointer to the particular position
    fstream& GetFile();                                     // get the currfile
    void IncNumPages();                                     // increment the numPages
    int GetNumPages() const;                                // return the numPages
    void SetUse(const int& index, const int& use_bit);      // maintain a global char array which keeps track of 
                                                            // the use_bits of pages
    int GetUse(const int& index) const;                     // return the use_bit of the particular page

private:
    //FILE* currFile;
    fstream currFile;
    int numPages;
    array<int, MAXPAGES> pages;
};

#endif

DSMgr.cpp

#include "../inc/dsmgr.hpp"

inline DSMgr::DSMgr() : numPages(0){ };

inline int DSMgr::OpenFile(std::string filename){
    this->currFile.open(filename, ios::out | ios::in | ios::binary);
    if(this->currFile.is_open()){
        cout << "success: the file " << filename << " open successfully and reserve in the class DSMgr." << endl;
        return 1;
    }else{
        cout << "error: can't open the file." << filename << endl;
        abort();
    }   
}

inline int DSMgr::CloseFile(){
    currFile.close();
    if(currFile.is_open()){
        cout << "error: can't close the current file." << endl;
        abort();
    }
    return 1;
}

inline bFrame DSMgr::ReadPage(const int& page_id){
int pos = page_id * FRAMESIZE;
    currFile.seekg(pos, ios::beg);
    bFrame read_data;
    currFile.read(read_data.field, FRAMESIZE);
    return read_data;
}

inline int DSMgr::WritePage(const int& page_id, bFrame frm){
int pos = page_id * FRAMESIZE;
    if(currFile.is_open()){
        currFile.seekp(pos, ios::beg);
        currFile.write(frm.field, strlen(frm.field));
    }else{
        cout << "error: the current file is not open, fail to write into." << endl;
        abort();
    }
}

inline int DSMgr::Seek(const int& offset, const int& pos){
    if(this->currFile.is_open()){
        this->currFile.seekp(pos   offset, ios::beg);
        return 1;
    }else{
        cout << "error: the current file is not open so that can not seek file pointer." << endl;
        abort();
    }
}

#include <thread>
#include <chrono>
// for sleep_for()
inline fstream& DSMgr::GetFile(){
    if(this->currFile.is_open()){
        return this->currFile;
    }else{
        cout << "warnning: the current file is not open which may influence getting file." << endl;
        std::this_thread::sleep_for(chrono::duration<int>(2));
    }
}

inline void DSMgr::IncNumPages(){
      this->numPages;
}

inline int DSMgr::GetNumPages() const{
    return this->numPages;
}

inline void DSMgr::SetUse(const int& index, const int& use_bit){
    // assume that the id of pages mounts from zero
    // convert use_bit into char
    int use_bit_char = use_bit   48;
    use_bits[index] = char(use_bit_char);
}

inline int DSMgr::GetUse(const int& index) const{
    int use_bit = int(use_bits[index]) - 48;
    return use_bit;
}

predefine.hpp

#ifndef __PREDEFINE_HPP__
#define __PREDEFINE_HPP__

#include <array>
#include <iostream>
using namespace std;

// a block called page in physical memory and frame in buffer.
#define MAXPAGES 50000
#define FRAMESIZE 4096
struct bFrame
{
    char field[FRAMESIZE];
};

#define DEFBUFSIZE 1024
extern array<bFrame*, DEFBUFSIZE> buf;      // the buf consists of an array of frame


// Buffer Control Blocks
struct BCB{
    BCB();
    int page_id;
    int frame_id;
    int latch;
    int count;
    int dirty;
    BCB* next;
};

// the arrays below are defined in the class BMgr
// extern array<int, DEFBUFSIZE> hTable;       // frame_id -> page_id
// extern array<BCB, DEFBUFSIZE> hTable_b;     // page_id -> BCB

inline const int HashCov(const int& id){    // compute hash value
    return (id % DEFBUFSIZE);
}

// double-linked list to manage least recently use list
// assign the head of the list to 'MRU' interface, 
// while the tail is 'LRU' interface that should be chosen to replace
#include <list>
static list<int> LM;

// a string that keeps use_bits of pages
static char use_bits[MAXPAGES];

extern int ext;
#endif

testt.cpp

#include "../inc/dsmgr.hpp"

int main(){
    DSMgr _dd = DSMgr();
    return 0;
}

And the following is error information.

/usr/bin/clang   -std=c  14 -fcolor-diagnostics -fansi-escape-codes -g /Users/luzijian/Documents/Document/Ustc/FirstTerm/AdvancedDatabaseSystem/lab/src/*.cpp -o /Users/luzijian/Documents/Document/Ustc/FirstTerm/AdvancedDatabaseSystem/lab/src/../bin/testt
/Users/luzijian/Documents/Document/Ustc/FirstTerm/AdvancedDatabaseSystem/lab/src/dsmgr.cpp:42:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
}
/Users/luzijian/Documents/Document/Ustc/FirstTerm/AdvancedDatabaseSystem/lab/src/dsmgr.cpp:64:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
}
2 warnings generated.
Undefined symbols for architecture arm64:
  "DSMgr::DSMgr()", referenced from:
      _main in testt-a26be3.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

However, when I try to define another class in a test file, it runs successfully.

lru.hpp

#ifndef __LRU_HPP__
#define __LRU_HPP__


class LRU{
public:
    int replace(const int& frame_id);                   // move a frame to the first place if it is not
    int add(const int& frame_id);                       // add a new frame into the list
    int select(const int& pos);    // select a victim frame and remove it
                                                        // the second parameter is to control which frame to return   
};

#endif

lru.cpp

#include "../inc/lru.hpp"
#include "../inc/predefine.hpp"

inline int LRU::replace(const int& frame_id){
    if(frame_id != LM.front()){

auto pos = find(LM.begin(), LM.end(), frame_id);
int item = *pos;
        LM.erase(pos);
        LM.push_front(item);
    }
    return 1;
}

inline int LRU::add(const int& frame_id){
    // compare the size of LM list with DEFBUFSIZE
    if(DEFBUFSIZE <= LM.size()){
        cout << "error: the capacity of LM list is full, can not add a new frame." << endl;
        return 0;
    }else{
        LM.push_front(frame_id);
    }
    return 1;
}

inline int LRU::select(const int& offset){
    auto pos = LM.end();
    advance(pos, -offset-1);
    return *pos;
}

testt.cpp

#include "../inc/lru.hpp"

int main(){
    LRU _ll = LRU();
    return 0;
}

When I define the LRU class in the testt.cpp file and compile it, there is no error.

Is there anyone can help me solve this problem.

CodePudding user response:

For some reason you have declared everything as inline. If you want inline methods then you should move the definitions to the header files.

But if I were you I would just remove inline from each of your methods.

CodePudding user response:

inline indicates to the compiler to not export a symbol from a translation unit.

This is useful when defining functions and methods in header files as it avoids multiple symbol definitions when multiple translation units use a header. Each translation unit essentially gets its own copy of the function and there's no conflict (as long as the inline definitions are included in every translation unit that needs them)

Marking methods inline in a cpp file however means that your cpp file isn't exporting the symbols for other cpp files to use, this leads to undefined references.

  • Related