0

I've been stuck on this issue in the past week. when I compiled the code with the VS Code Insiders - Code Runner Extension or the command: clang++ -std=c++14 main.cpp, it gives me the below error:

Undefined symbols for architecture arm64:
  "LinkedList::insertHead(int)", referenced from:
      _main in main-6d6a24.o
  "LinkedList::insertTail(int)", referenced from:
      _main in main-6d6a24.o
  "operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, LinkedList const&)", referenced from:
      _main in main-6d6a24.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

However, I was able to compile the code with the Makefile below:

all: main

main: main.o linkedList.o
    clang++ -std=c++14 -o $@ $^

main.o: main.cpp linkedList.h
    clang++ -std=c++14 -c $<

linkedList.o: linkedList.cpp linkedList.h
    clang++ -std=c++14 -c $<

clean:
    rm -f main *.o
    rm -f linkedList *.o

And also it would work if I put the int main() {} inside the linkedList.cpp. I guess maybe there are some kind of linker issue? It's been mentioned a lot when I searched the error.

Here is the code: main.cpp:

#include "linkedList.h"
#include <iostream>

int main() {
  LinkedList l;
  LinkedList l2;

  for (int i = 0; i < 10; i++) {
    l.insertHead(i);
  }

  for (int i = 0; i < 10; i++) {
    l2.insertTail(i);
  }

  std::cout << l << std::endl;
  std::cout << l2 << std::endl;

  return 0;
}

linkedList.h:

#include <iostream>

struct Node {
  int data;
  Node *next = nullptr;
};

class LinkedList {
 private:
  Node *head;
  Node *tail;
  void inserFirst(int);
  Node *createNode(int);

 public:
  void insertHead(int);
  void insertTail(int);
  friend std::ostream &operator<<(std::ostream &out, const LinkedList &list);
};

linkedList.cpp:

#include "linkedList.h"
  
void LinkedList::inserFirst(int item) {
  Node *n = createNode(item);
  head = n;
  tail = n;
}

Node* LinkedList::createNode(int item) {
  Node *n = new Node;
  n->data = item;
  n->next = nullptr;
  return n;
}

void LinkedList::insertHead(int item) {
  if (head == nullptr) {
    inserFirst(item);
  } else {
    Node *n = createNode(item);
    n->next = head;
    head = n;
  }
}

void LinkedList::insertTail(int item) {
  if (head == nullptr) {
    inserFirst(item);
  } else {
    Node *n = createNode(item);
    tail->next = n;
    tail = n;
  }
}

std::ostream &operator<<(std::ostream &out, const LinkedList &list) {
  Node *n = list.head;
  while (n != nullptr) {
    out << n->data;
    n = n->next;
  }
  return out;
}

What made me confused is since the code can be compiled with the Makefile, why wouldn't it be compiled with the code runner?

Just a quick update: I tested the code on CLion and it was compiled, so I'm gonna reinstall the code runner extension on Vs Code to see if it fixes the problem.

Gama11
  • 31,714
  • 9
  • 78
  • 100
JohnL10000
  • 1
  • 1
  • 1
  • 5
  • Does this answer your question? [C++: Undefined symbols for architecture x86\_64](https://stackoverflow.com/questions/20313267/c-undefined-symbols-for-architecture-x86-64) – Siguza Mar 06 '21 at 04:40
  • Because you're not compiling `linkedList.cpp`. – Siguza Mar 06 '21 at 05:14
  • Right, I deleted my previous reply cuz C++: Undefined symbols for architecture x86_64 did help with a clue. I modified the settings.json and now it works, thank you! – JohnL10000 Mar 06 '21 at 05:19

4 Answers4

6

For some reason, the vscode on MAC does not link the files automatically. You may have to run the code in the terminal.

g++ main.cpp linkedList.cpp -o main

Then you can execute the program

./main

N.B. Don't forget to be on the same path of the files you are compiling

zizutg
  • 1,070
  • 14
  • 20
1

When running C++ code using XCode IDE, the CPP files are not added to the target you're trying to build automatically. Even though you can see them under the target directory but it doesn't mean it's added to the compiled CPP files of this target.

You can add your source file to the target membership on the right side of your XCode.

on the other hand, you were able to build using Makefile and the other option because you're specifying the sources you need to compile manually as here

linkedList.o: linkedList.cpp linkedList.h
    clang++ -std=c++14 -c $<

In general, when you try to build a C++ target using XCode and you faced undefined symbols error, this means you're missing the implementation of some headers/functions

Mazen Ak
  • 152
  • 7
1

A quite common error for mac users especially for mac m1, m2's. This I believe is caused by the underlying architecture. Fix the error by listing all your files that need linking in the compile command.

g++ file1.cpp file2.cpp ... -o main

My example is:

g++ main.c++ agent.c++ model.c++ -o main

Well until we do get visual studio working with CPP for mac. Use this.

-1

Found a "temporary" answer: In Code-runner: Executor Map, edit in settings. json, I changed

"cpp": "cd $dir && clang++ -std=c++14 $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",

by adding linked_list.cpp (implementation file) right after $fileName

"cpp": "cd $dir && clang++ -std=c++14 $fileName linked_list.cpp -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
JohnL10000
  • 1
  • 1
  • 1
  • 5