C++ and VS Code on Windows

What You’ll Need

  • Visual Studio Code
  • C++ compiler (MinGW-w64 for Windows)
  • VS Code C++ extensions

Step 1 — Install a C++ Compiler (MinGW-w64)

Windows doesn’t ship with a C++ compiler, so we install MinGW-w64, which gives you g++ on the command line.

  1. Go to https://winlibs.com and download the latest GCC release for Windows (choose the Win64 / UCRT / without LLVM build as a .zip)
  2. Extract the zip — you’ll get a folder called mingw64
  3. Move that folder somewhere permanent, e.g. C:\mingw64
  4. Add it to your PATH:
    1. Open the Start menu and search for Environment Variables
    2. Click Edit the system environment variables
    3. Click Environment Variables…
    4. Under System variables, select Path and click Edit
    5. Click New and add: C:\mingw64\bin
    6. Click OK on all dialogs

Open a new Command Prompt and verify it worked:

g++ --version

You should see something like g++ (MinGW-w64) 13.x.x.


Step 2 — Install Visual Studio Code

Download and install from: https://code.visualstudio.com

During install, check the box for “Add to PATH” — this lets you open VS Code from the command line.


Step 3 — Install C++ Extensions in VS Code

  1. Open VS Code
  2. Go to the Extensions tab (left sidebar or Ctrl+Shift+X)
  3. Search for and install:
    • C/C++ by Microsoft
    • C/C++ Extension Pack by Microsoft (includes the debugger and IntelliSense)

Step 4 — Create and Run a Simple C++ Program

  1. Create a new folder for your project (e.g., cpp-labs)
  2. Open the folder in VS Code: File → Open Folder
  3. Create a new file: hello.cpp

Paste the following:

#include <iostream>

int main() {
    std::cout << "Hello, world!" << std::endl;
    return 0;
}
  1. Open the Terminal in VS Code: Terminal → New Terminal
  2. Compile the code:
g++ hello.cpp -o hello
  1. Run the program:
.\hello

You should see: Hello, world!


Step 5 — Configure VS Code to Build with One Keystroke

Set up a VS Code build task so you don’t have to type compile commands every time.

Create the tasks file

  1. In VS Code, go to Terminal → Configure Default Build Task
  2. Select C/C++: g++ build active file

VS Code will create a .vscode/tasks.json file. Replace its contents with this:

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Build C++",
      "type": "shell",
      "command": "g++",
      "args": [
        "-g",
        "-std=c++17",
        "${file}",
        "-o",
        "${fileDirname}\\${fileBasenameNoExtension}.exe"
      ],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "problemMatcher": ["$gcc"]
    }
  ]
}

Note: The -g flag includes debug information — required for the debugger to work. The -std=c++17 flag enables modern C++ features. On Windows, the output file gets an .exe extension.

Now build any open .cpp file by pressing Ctrl+Shift+B.


Step 6 — Set Up the Debugger

The debugger lets you pause your program mid-execution, inspect variables, and step through code line by line.

Create the launch configuration

  1. Click the Run and Debug icon in the left sidebar (or press Ctrl+Shift+D)
  2. Click create a launch.json file
  3. Select C++ (GDB/LLDB), then g++ — Build and debug active file

VS Code will create .vscode/launch.json. Replace its contents with:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Build and Debug",
      "type": "cppdbg",
      "request": "launch",
      "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${fileDirname}",
      "environment": [],
      "externalConsole": false,
      "MIMode": "gdb",
      "miDebuggerPath": "C:\\mingw64\\bin\\gdb.exe",
      "preLaunchTask": "Build C++"
    }
  ]
}

Note: Make sure miDebuggerPath matches where you installed MinGW-w64. If you put it somewhere other than C:\mingw64, update that path accordingly.

Debugger Controls

Action How
Set a breakpoint Click in the gutter (left of the line number) — a red dot appears
Start debugging F5 or click the green play button
Step over a line F10 — runs the line, stays at the same level
Step into a function F11 — follows the call inside the function
Step out Shift+F11 — finishes the function and returns
Continue to next breakpoint F5
Stop debugging Shift+F5
Inspect a variable Hover over it while paused, or check the Variables panel

Step 7 — Try It with a Larger Program

Here’s a student grade tracker with enough complexity to make debugging practice worthwhile. It uses functions, loops, vectors, and structs.

Create a new file called grades.cpp and paste this in:

#include <iostream>
#include <vector>
#include <string>
#include <numeric>
#include <algorithm>
#include <iomanip>

struct Student {
    std::string name;
    std::vector<double> scores;
};

double average(const std::vector<double>& scores) {
    if (scores.empty()) return 0.0;
    double total = std::accumulate(scores.begin(), scores.end(), 0.0);
    return total / scores.size();
}

char letterGrade(double avg) {
    if (avg >= 90) return 'A';
    if (avg >= 80) return 'B';
    if (avg >= 70) return 'C';
    if (avg >= 60) return 'D';
    return 'F';
}

double highest(const std::vector<double>& scores) {
    return *std::max_element(scores.begin(), scores.end());
}

double lowest(const std::vector<double>& scores) {
    return *std::min_element(scores.begin(), scores.end());
}

void printStudentReport(const Student& s) {
    double avg = average(s.scores);
    std::cout << "\nStudent: " << s.name << "\n";
    std::cout << "  Scores:  ";
    for (double score : s.scores) {
        std::cout << std::setw(6) << score;
    }
    std::cout << "\n";
    std::cout << std::fixed << std::setprecision(1);
    std::cout << "  Average: " << avg << "\n";
    std::cout << "  Highest: " << highest(s.scores) << "\n";
    std::cout << "  Lowest:  " << lowest(s.scores) << "\n";
    std::cout << "  Grade:   " << letterGrade(avg) << "\n";
}

void printClassSummary(const std::vector<Student>& students) {
    std::cout << "\n========== Class Summary ==========\n";
    double classTotal = 0.0;
    std::string topStudent;
    double topAvg = -1.0;

    for (const Student& s : students) {
        double avg = average(s.scores);
        classTotal += avg;
        if (avg > topAvg) {
            topAvg = avg;
            topStudent = s.name;
        }
    }

    double classAvg = classTotal / students.size();
    std::cout << std::fixed << std::setprecision(1);
    std::cout << "Number of students: " << students.size() << "\n";
    std::cout << "Class average:      " << classAvg << " (" << letterGrade(classAvg) << ")\n";
    std::cout << "Top student:        " << topStudent << " (" << topAvg << ")\n";

    int countA = 0, countB = 0, countC = 0, countD = 0, countF = 0;
    for (const Student& s : students) {
        char g = letterGrade(average(s.scores));
        if (g == 'A') countA++;
        else if (g == 'B') countB++;
        else if (g == 'C') countC++;
        else if (g == 'D') countD++;
        else countF++;
    }

    std::cout << "\nGrade distribution:\n";
    std::cout << "  A: " << countA << "\n";
    std::cout << "  B: " << countB << "\n";
    std::cout << "  C: " << countC << "\n";
    std::cout << "  D: " << countD << "\n";
    std::cout << "  F: " << countF << "\n";
}

int main() {
    std::vector<Student> roster = {
        {"Alice",   {92, 88, 95, 91, 84}},
        {"Bob",     {73, 65, 70, 68, 72}},
        {"Carol",   {85, 90, 88, 93, 96}},
        {"David",   {55, 60, 58, 62, 50}},
        {"Eva",     {78, 82, 79, 81, 76}},
        {"Frank",   {100, 98, 95, 99, 97}},
        {"Grace",   {40, 45, 38, 50, 42}},
    };

    std::cout << "========== Individual Reports ==========";
    for (const Student& s : roster) {
        printStudentReport(s);
    }

    printClassSummary(roster);
    return 0;
}

Compile and run it

g++ -g -std=c++17 grades.cpp -o grades
.\grades

Things to try with the debugger

  1. Set a breakpoint on the printStudentReport call inside the for loop in main. Press F5. The program pauses for each student — expand the s variable in the Variables panel to see their name and scores.
  2. Step into average() from inside printStudentReport using F11. Watch total grow as accumulate runs.
  3. Step over lines in printClassSummary and watch topStudent and topAvg update as each student is evaluated.
  4. Hover over variables while paused — VS Code shows their current value inline.

Quick Reference

Task Shortcut
Build Ctrl+Shift+B
Start / continue debugging F5
Step over F10
Step into F11
Step out Shift+F11
Stop debugging Shift+F5
Toggle breakpoint Click gutter or F9
Open terminal Ctrl+`

Troubleshooting

“g++ is not recognized as a command”
The MinGW-w64 bin folder isn’t on your PATH, or you didn’t open a new terminal after adding it. Double-check the PATH entry points to C:\mingw64\bin (or wherever you extracted it), then close and reopen your terminal.

“miDebuggerPath does not exist”
Update the miDebuggerPath in launch.json to match your actual MinGW-w64 install location. Right-click gdb.exe in File Explorer and choose Properties to confirm the full path.

Breakpoints are grey (unverified)
Make sure you compiled with the -g flag. Without it, the debugger has no line information to work with.

Changes to code don’t show up when debugging
Always rebuild (Ctrl+Shift+B) before starting a new debug session, or use the Build and Debug launch config which rebuilds automatically.

Program output disappears immediately
If you’re running outside VS Code and the terminal window closes before you can read the output, add this line before return 0; in main:

std::cin.get();

This pauses the program until you press Enter. You won’t need this inside VS Code’s integrated terminal.

Scroll to Top