skip to Main Content

I’m trying to compile a C++ program "test.cpp" that includes a custom file "Cars.h" using VS Code. However it causes a build error even though I’m pretty sure I did everything right.

My directory structure:

Test
├── .vscode
│   ├── tasks.json
├── include
│   ├── Cars.cpp
│   └── Cars.h
├── test.cpp

test.cpp

#include <iostream>
#include "include/Cars.h"

using namespace std;

int main(){
    Cars c;
    cout << "Hello!" << endl;
    c.printcars();  
}      

Cars.cpp

#include <iostream>

class Cars{

    public:
        void printcars(){
            std::cout << "Cars" << std::endl;
        }

};

Cars.h

#ifndef CARS_H
#define CARS_H

class Cars {
    public:
        void printcars();

};

#endif

tasks.json

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "cppbuild",
            "label": "buildFile",
            "command": "g++",
            "args": [
                "-o",
                "${fileBasenameNoExtension}.exe",
                "${file}",
                "${workspaceFolder}\include\*.cpp",
                "${workspaceFolder}\include\*.h",
                "-I${workspaceFolder}\include"
            ],
            "options": {
                "cwd": "${workspaceFolder}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": "build"
        }
        
    ]
}

Error:

test.cpp:(.text+0x37): undefined reference to `Cars::printcars()'
collect2.exe: error: ld returned 1 exit status

Build finished with error(s).

 *  The terminal process terminated with exit code: -1. 
 *  Terminal will be reused by tasks, press any key to close it. 

I am certain that it’s a linker error, since the program runs perfectly when I include Cars.cpp instead of Cars.h. However this is a test and I am required to include the header file only.

2

Answers


  1. There a few things wrong. But the main one is that you have defined the class Cars twice, once in cars.h and once in cars.cpp.

    cars.cpp should look like this

    #include <iostream>
    #include "cars.h"
    
    void Cars::printcars(){
        std::cout << "Cars" << std::endl;
    }
    

    Don’t define Cars twice, instead include cars.h in cars.cpp and use an out of class definition for Cars::printcars.

    The other thing I don’t like is your tasks.json file. Don’t use ${file}, that is the file you are currently editing. I’m sure you can see that might cause problems, you can only build you code if you happen to be editing main.cpp. Secondly don’t compile header files, so remove "${workspaceFolder}\include\*.h"

    Something like

            "args": [
                "-o",
                "${fileBasenameNoExtension}.exe",
                "${workspaceFolder}\main.cpp",
                "${workspaceFolder}\include\*.cpp",
                "-I${workspaceFolder}\include"
            ],
    

    seems right to me (but I’m no expert on VSCode).

    Login or Signup to reply.
  2. Your main issues are,

    1. You have not included the header file within your Cars.cpp file, so the linker has no idea where your defined code is for that Cars.h file.
    2. In Cars.cpp, you are not defining the function that you’ve declared within the class in Cars.h

    To fix these, you must first include the header file within your Cars.cpp file

    so it would look like this..

    #include <iostream>
    #include "Cars.h"
    
    class Cars {
    
    public:
        void printcars() {
            std::cout << "Cars" << std::endl;
        }
    
    };
    

    And you need to define the function within Cars.cpp like so:

    #include <iostream>
    #include "Cars.h"
    
    void Cars::printcars() {
        std::cout << "Cars" << std::endl;
    }
    

    This should hopefully fix your linker error.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search