EECS 280 Tutorials

Setup up VS Code for C/C++ on Windows

Visual Studio Code is a lightweight, easy-to-use, source code editor with debugging support. It runs on macOS, Windows, and Linux (including CAEN Linux). Visual Studio Code is not the same program as Visual Studio.

This tutorial is specific to Windows. Looking for the macOS version?

If you already have VS Code installed with the C/C++ extensions, skip to the Create a project section.

Prerequisites

Complete the WSL tutorial to ensure your Windows and WSL installations are up-to-date and you have CLI tools installed.

Review our Command Line Interface (CLI) tutorial.

Make sure you have a compiler and a debugger installed. Your version might be different.

$ g++ --version
g++ (GCC) 8.5.0 20210514
$ gdb --version
GNU gdb (GDB)

Install

Ensure the prerequisites above are satisfied, then install VS Code from the web https://code.visualstudio.com/.

Select each of the options below during installation.

Open VS Code. You can skip the welcome screen.

WSL Extension

Install the WSL Extension, which allows the VS Code backend to run in WSL where the C++ compiler lives.

  1. Open the extensions panel from the left sidebar.
  2. Search for WSL.
  3. Click “Install”.

Next, connect to WSL:

  1. Click the button in the bottom left corner.
  2. Select “Connect to WSL” from the menu.

Now, the button in the bottom left should say “WSL: Ubuntu”. For any C++ development, make sure VS code is always connected to WSL.

Microsoft C++ Extension

Pitfall: Make sure you’re connected to WSL before installing the C++ Extension. Check the button in the bottom left.

Install the C++ Extension to run in WSL.

  1. Open the extensions panel from the left sidebar.
  2. Search for C++.
  3. Click “Install”.

Note that you need the “C/C++” extension. You do not need the “C/C++ Extension Pack”.

Clear out the search bar in the extensions panel. You should see:

Create a project

To create a VS Code project, create a folder (directory). There are many ways to create folders: File Explorer, VS Code interface, VS Code integrated terminal, and the system terminal. We’ll use the system terminal and call our example project p1-stats.

Open the Terminal (Ubuntu Bash Shell).

Navigate to your home directory, create a new directory, then move into the new directory. Your folder location might be different. Here’s some help with cd, the tilde ~, and mkdir.

$ mkdir ~/eecs280
$ cd ~/eecs280
$ mkdir p1-stats
$ cd p1-stats

Pitfall: Avoid paths that contain spaces. Spaces causes problems with some command line tools.

Bad Example Good Example
EECS 280/ eecs280/
Project 1 Stats/ p1-stats/

Pitfall: Linux (Ubuntu) has a separate home directory. Storing code in your Windows home directory can cause slowdowns.

$ pwd
/home/awdeorio ...         # Good, Linux home
/c/mnt/Users/awdeorio ...  # Bad, Windows home

Here’s how to access your Linux files from Windows.

Start VS Code and open your project folder. View > Command Palette (ctrl + shift + p). Search for and select WSL: Open Folder in WSL.

Pro-tip: Here’s a quick way to open VS Code to a specific project folder from the command line. First make sure you’re in the directory that contains your source code.

$ ls
main.cpp ...
$ code .

Note: If you’ve just installed VS Code, you’ll need to restart your terminal before the code command will work.

Add new files

Start VS Code and open your project folder. View > Command Palette (ctrl + shift + p). Search for and select WSL: Open Folder in WSL.

Select the add file icon and give it a name, e.g., main.cpp.

Alternatively, create your main.cpp file from the command line using touch.

$ touch main.cpp

Copy-paste this Hello World program into your main.cpp. Save the updated file.

#include <iostream>
using namespace std;

int main() {
  cout << "Hello World!\n";
}

Add existing files

If you have starter files, add them to your project directory. This example is from EECS 280 Project 1, but this tutorial doesn’t require understanding the files. Your URL or files might be different.

Pitfall: Make sure you’re in the directory containing your source code.

$ ls
main.cpp

Pro-tip: Copy/paste instructions for WSL.

We’ll use the terminal to download, unpack, and move the starter files into the directory that already contains main.cpp. Your URL or folder might be different.

$ wget https://eecs280staff.github.io/p1-stats/starter-files.tar.gz
$ tar -xvzf starter-files.tar.gz
$ mv starter-files/* .
$ rm -rf starter-files starter-files.tar.gz

You should see your new files in your project directory.

$ tree
.
├── Makefile
├── main.cpp
├── main_test.in
├── main_test.out.correct
├── main_test_data.tsv
├── p1_library.cpp
├── p1_library.hpp
├── stats.hpp
├── stats_public_test.cpp
└── stats_tests.cpp.starter

You should see your new files appear in VS Code.

Rename files

If you need to rename any files, you can do this from VS Code or from the command line. In EECS 280, you’ll need to rename any files that end in .starter.

Right click a file and select “rename”. Change the file name. In EECS 280, you’ll do this to any file that ends in .starter.

Pro-tip: You can also rename files the command line, for example:

$ mv stats_tests.cpp.starter stats_tests.cpp

Compile and Run

VS Code uses an executable you build at the command line.

First, compile and run your executable at the command line.

$ touch stats.cpp  # Needed for EECS 280 P1
$ make main.exe
$ ./main.exe
Hello World!

Pitfall: Make sure you’re in the directory containing your source code.

$ ls
main.cpp ...

Pitfall: If you’re in EECS 280 and get an error like this, add a new file stats.cpp. It’s OK if the file is empty for now.

$ make main.exe
make: *** No rule to make target `stats.cpp', needed by `main.exe'.  Stop.

Pitfall: VS Code debugging will fail if there are no debugging symbols. Double check the output of make and verify that you see -g being used in the commands. The EECS 280 defaults include -g.

$ make main.exe
g++ ... -g main.cpp ...

If you don’t have a Makefile, you can compile manually. We don’t recommend this for EECS 280 students.

$ g++ -g main.cpp -o main.exe

Pitfall: Make sure you’re in WSL mode.

If you accidentally open VS Code in Windows mode, you won’t see “WSL: Ubuntu” in the lower left corner, your integrated terminal may default to powershell, and compiling/running C++ code won’t work correctly.

Open the Command Palette with View > Command Palette (ctrl + shift + p). Search for and select Reopen Folder in WSL (or Open Folder in WSL if you hadn’t opened anything yet).

Select the file you would like to run. Navigate to the debugging pane.

Click “create a launch.json file”.

If you are prompted to select a debugger, select C++ (GDB/LLDB).

Click “Add Configuration”. If the button does not appear in the bottom-right corner, select “Run” from the top menu, then select “Add Configuration”.

Select the “C/C++ (gdb) Launch” configuration. This will create a default launch.json (Microsoft Reference).

Edit the program and cwd fields in launch.json. Save the updated file. Your program name might be different.

Edit launch.json program

If you already have a working launch.json and want to debug a different program, edit the program field launch.json. Your program name might be different. Make sure cwd is set to "${workspaceFolder}".

{
    "program": "${workspaceFolder}/main.exe",
    ...
    "cwd": "${workspaceFolder}",
}

Run

Click the triangle to run. You’ll see your program’s output in the terminal window at the bottom.

Pitfall: Remember to build your executable at the command line first.

$ make main.exe

Pitfall: If you’re having trouble running your program, delete your launch.json and try the compile and run section again.

Pitfall: If you encounter an error like the one below, it is likely that VS Code is in Windows mode rather than WSL. Follow the instructions in WSL Mode Pitfall to reopen the folder in WSL mode.

Pitfall: If you see output like the following in the terminal:

And an error like this in the debug console:

The likely cause is that you have WSL 1 rather than WSL 2. Follow the instructions in the WSL tutorial to upgrade to WSL 2, install the CLI tools, and then restart this tutorial.

Sanitizers

We recommend enabling the address sanitizer and undefined behavior sanitizer. These will help you find memory errors like going off the end of an array or vector.

First, edit your Makefile and add the CXXFLAGS recommended by the ASAN Quick Start.

Edit the "environment" property in your launch.json. If there’s already an empty "environment": [], replace it. If there isn’t one, add it after the "args" property.

  "environment": [
    {
      "name": "ASAN_OPTIONS",
      "value": "abort_on_error=1:detect_leaks=0"
    }
  ],

Input redirection

Skip this subsection your first time through the tutorial. You can come back to it.

If you’re unfamiliar with input redirection, first read the CLI tutorial section on input redirection.

To configure input redirection, edit launch.json. These changes are for the Microsoft C/C++ extension.

{
    "configurations": [
        {
            ...
            "program": "${workspaceFolder}/main.exe",
            "args": ["<", "main_test.in"],
            ...
        }
    ]
}

Pitfall: Make sure you’re using the Microsoft C++ extension. You should see cppdbg in your launch.json. If not, delete your launch.json and try the compile and run section again.

{
    "configurations": [
        {
            "type": "cppdbg",
            ...

Arguments and options

Skip this subsection for EECS 280 project 1.

Arguments and options are inputs to a program typed at the command line. Here’s an example from EECS 280 Project 5:

$ ./main.exe train_small.csv test_small.csv --debug

To run a program with options or arguments in VS Code, edit launch.json. Each option or argument should goes in a separate comma-separated string.

{
    "configurations": [
        {
            ...
            "program": "${workspaceFolder}/main.exe",
            "args": ["train_small.csv", "test_small.csv", "--debug"],
            ...
        }
    ]
}

Debug

In this section, we’ll set a breakpoint, which pauses the debugger. Then, we’ll cover some of the options to continue execution.

Step Over Run one line of code, stepping over any function calls by running the whole function in one step.

Step Into Run one line of code, stepping into any function calls to execute them line-by-line.

Step Out Run the program until it returns from the current function (or until the next breakpoint).

Continue Run the program until the next breakpoint.

Example code

To get started, copy this example main.cpp into your editor.

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

double sum (const vector<double> &data) {
  double total = 0;
  for (size_t i=0; i<data.size(); ++i) {
    total += data[i];
  }
  return total;
}

int main() {
  vector<double> data;
  data.push_back(10);
  data.push_back(20);
  data.push_back(30);
  cout << "sum(data) = " << sum(data) << endl;
}

Breakpoint

Select the file you want to debug. Set a breakpoint by clicking to the left of a line number. A breakpoint tells the program to pause.

Run

Select the debugging pane, then run the debugger. The program pauses at the breakpoint. The yellow indicator highlights the next line of code to be run.

Pitfall: Don’t forget to compile!

$ make main.exe                # With a Makefile
$ g++ -g main.cpp -o main.exe  # Without a Makefile

Step over

Click “Step Over” a few times until you reach the highlighted line of code

Inspect

Hover over a variable to inspect its value. You can also see values in the VARIABLES pane.

If you have trouble viewing the contents of a container like this screenshot, see Pretty Printing STL Containers with gdb.

Step into

Click “Step Into”. The cursor enters the sum() function.

Step out

Click “Step Out”. The sum() function completes, and the program pauses again.

Continue

Press “Continue” to run the program to the next breakpoint, or the end, whichever comes first.

Troubleshooting

This section is for common problems and solutions.

Reset

To reset VS Code project settings and starter files, first quit VS Code. Make a backup copy of your files, and then delete your project directory. Your project directory might be different.

$ pwd
/Users/awdeorio/src/eecs280
$ cp -a p1-stats p1-stats.bak  # Backup
$ rm -rf p1-stats              # Delete

VS Code has a lot of settings and extensions. You can reset the entire user interface and remove all extensions using these commands (Based on Microsoft instructions). This is optional.

Replace awdeorio with your Windows username. List the usernames with ls /mnt/c/Users/.

$ rm -rf ~/.vscode
$ rm -rf "/mnt/c/Users/awdeorio/.vscode"
$ rm -rf "/mnt/c/Users/awdeorio/AppData/Roaming/Code"

Then, return to the Create a project section.

Intellisense C++ Standard

Intellisense is the feature that indicates compiler errors with red squiggly lines and suggests code completions. If the C++ standard is out-of-date, you’ll see squiggles where you shouldn’t.

First, you should already have the C/C++ extension installed (Instructions).

Next, open VS Code’s Command Palette with View > Command Palette (ctrl + shift + p). Search for and select C/C++: Edit Configurations (JSON). This will open the file c_cpp_properties.json.

Modify the cStandard and cppStandard settings in c_cpp_properties.json. Don’t change any other settings. Save the file.

{
    "configurations": [
        {
            ...
            "cStandard": "c17",
            "cppStandard": "c++17",
            ...
        }
    ],
    ...
}

C/C++ extension alternatives

There are multiple options for C/C++ extensions.

Microsoft C/C++ extension provides debugging support and intellisense on Windows, Linux and macOS. At the time of this writing (January 2023) debug support has a bug on macOS.

CodeLLDB provides debugging support for those using the LLVM compiler. Apple’s compiler on macOS is based on LLVM.

clangd provides intellisense and requires the clangd language server, which is related to the LLVM compiler. We do not recommend installing the clangd extension with the Microsoft C/C++ extension because multiple intellisense providers can produce confusing results.

WSL lets us develop with Linux-based utilities like the g++ compiler.

Acknowledgments

Original document written by Andrew DeOrio awdeorio@umich.edu.

This document is licensed under a Creative Commons Attribution-NonCommercial 4.0 License. You’re free to copy and share this document, but not to sell it. You may not share source code provided with this document.