So I was practicing with a tutorial series on C projects for Linux. In order to create the makefile I did CTR SHIFT P to go into Palet, searched for make file, selected the correct option, and selected C project. In the tutorial, the person changed src in the make file to a static path ie: pwd. That worked. When he changed back to src and after moving the files into the src folder like he did, doing make clean, and then make, I get this:
[termg@term-ms7c02 HelloWorldnonVR]$ make
g -std=c 11 -Wall -o obj/list.o -c src/list.cpp
g -std=c 11 -Wall -o obj/main.o -c src/main.cpp
g -std=c 11 -Wall -o HelloWorld obj/list.o obj/main.o
/usr/bin/ld: obj/main.o: in function `List::List()':
main.cpp:(.text 0x0): multiple definition of `List::List()'; obj/list.o:list.cpp:(.text 0x0): first defined here
/usr/bin/ld: obj/main.o: in function `List::List()':
main.cpp:(.text 0x0): multiple definition of `List::List()'; obj/list.o:list.cpp:(.text 0x0): first defined here
/usr/bin/ld: obj/main.o: in function `List::~List()':
main.cpp:(.text 0x2c): multiple definition of `List::~List()'; obj/list.o:list.cpp:(.text 0x2c): first defined here
/usr/bin/ld: obj/main.o: in function `List::~List()':
main.cpp:(.text 0x2c): multiple definition of `List::~List()'; obj/list.o:list.cpp:(.text 0x2c): first defined here
collect2: error: ld returned 1 exit status
make: *** [Makefile:37: HelloWorld] Error 1
[termg@term-ms7c02 HelloWorldnonVR]$
There are three files. A class and its header, and then the main. list.h is in the include subfolder for src. I currently cannot find any information about this problem, so any help would be appreciated. The tutorial had no issues with making or running the files. The VSCode extension is C/C Makefile Project. My system is Manjaro. I did do make clean and delete the makefile to start fresh, in case I hit the keyboard or something but same result persists. From what I am seeing, the issue is that there is no HelloWorld executable being created. HelloWorld is the appname in the template.
Narrowed the issue down to the header. Without constructors it works but with them it does not.
#include <iostream>
#include <vector>
using namespace std;
class List
{
private:
/* data */
protected:
public:
void print_menu(); //Prototype
void print_list();
void add_item();
void delete_item();
vector<string> list;
string name;
//constructor
List(/* args */);
//destructor
~List();
};
List::List(/* args */)
{
}
List::~List()
{
}
Any ideas on what is causing this?
CodePudding user response:
The error message tells you exactly what the problem is, if you learn the compiler-ese to interpret it:
main.cpp:...: multiple definition of `List::List()'; obj/list.o:list.cpp:...: first defined here
Here it's saying you have defined the constructor twice: once in main.cpp
and once in list.cpp
.
And, as is the case 99.99999% of the time, the compiler (well in this case technically the linker) is correct. You have defined the constructor and destructor in the header file, and you've included the header file in both the main.cpp
file and in the list.cpp
file, so the constructor and destructor are defined in both, just as the error says.
You need to put the constructor and destructor in the list.cpp
source file, not in the header file.
Alternatively you can put them inside the class itself, which makes them inline, and then you won't have this issue:
class List
{
private:
/* data */
protected:
public:
List(/* args */) {}
~List() {}
void print_menu(); //Prototype
Of course this only makes sense if they are small and simple enough to inline like this.