现已推出!阅读 10 月份的新功能和修复。

为 Microsoft C++ 配置 VS Code

在本教程中,您将配置 Visual Studio Code 以在 Windows 上使用 Microsoft Visual C++ 编译器和调试器。

配置 VS Code 后,您将在 VS Code 中编译和调试一个简单的 Hello World 程序。本教程不会教授您有关 Microsoft C++ 工具集或 C++ 语言的详细信息。对于这些主题,网络上有很多不错的资源可用。

如果您遇到任何问题,请随时在 VS Code 文档存储库 中提交有关本教程的问题。

先决条件

要成功完成本教程,您必须执行以下操作

  1. 安装 Visual Studio Code

  2. 安装 VS Code 的 C/C++ 扩展。您可以通过在扩展视图 (⇧⌘X (Windows、Linux Ctrl+Shift+X)) 中搜索“c++”来安装 C/C++ 扩展。

    C/C++ extension

  3. 安装 Microsoft Visual C++ (MSVC) 编译器工具集。

    如果您拥有最新版本的 Visual Studio,请从 Windows 开始菜单打开 Visual Studio 安装程序,并验证 C++ 工作负载是否已选中。如果未安装,请选中该框并选择安装程序中的“修改”按钮。

    您也可以安装 **使用 C++ 进行桌面开发** 工作负载,而无需完整的 Visual Studio IDE 安装。从 Visual Studio 下载 页面向下滚动,直到您在 **所有下载** 部分中看到 **Visual Studio 的工具**,然后选择 **Visual Studio 2022 构建工具** 的下载。

    Build Tools for Visual Studio download

    这将启动 Visual Studio 安装程序,该程序将弹出一个对话框,显示可用的 Visual Studio 构建工具工作负载。选中 **使用 C++ 进行桌面开发** 工作负载,然后选择 **安装**。

    Cpp build tools workload

**注意**:只要您也拥有有效的 Visual Studio 许可证(社区版、专业版或企业版),并且正在积极使用该许可证来开发该 C++ 代码库,就可以使用来自 Visual Studio 构建工具的 C++ 工具集与 Visual Studio Code 一起编译、构建和验证任何 C++ 代码库。

检查您的 Microsoft Visual C++ 安装

要从命令行或 VS Code 使用 MSVC,您必须从 **Visual Studio 开发人员命令提示符** 中运行。普通的 Shell(如 PowerShell、Bash 或 Windows 命令提示符)没有设置必要的路径环境变量。

要打开 Visual Studio 的开发者命令提示符,请在 Windows 开始菜单中开始键入“developer”,您应该会看到它出现在建议列表中。确切名称取决于您安装的 Visual Studio 或 Visual Studio 构建工具的版本。选择该项目以打开提示符。

Developer Command Prompt

您可以通过键入“cl”来测试您是否已正确安装 C++ 编译器 cl.exe,您应该会看到包含版本和基本用法说明的版权消息。

Checking cl.exe installation

如果开发者命令提示符使用 BuildTools 位置作为起始目录(您不希望将项目放在那里),请在开始创建新项目之前导航到您的用户文件夹(C:\users\{your username}\)。

**注意**:如果由于某种原因您无法从 **开发者命令提示符** 运行 VS Code,您可以在 在开发者命令提示符外部运行 VS Code 中找到用于使用 VS Code 构建 C++ 项目的解决方法。

创建 Hello World

从开发者命令提示符中,创建一个名为“projects”的空文件夹,您可以在其中存储所有 VS Code 项目,然后创建一个名为“helloworld”的子文件夹,导航到该文件夹,并在该文件夹中打开 VS Code(code)(.) 通过输入以下命令

mkdir projects
cd projects
mkdir helloworld
cd helloworld
code .

“code .”命令在当前工作文件夹中打开 VS Code,该文件夹成为您的“工作区”。在您完成本教程的过程中,您将看到在工作区中的 .vscode 文件夹中创建了三个文件

  • tasks.json(构建说明)
  • launch.json(调试器设置)
  • c_cpp_properties.json(编译器路径和 IntelliSense 设置)

添加源代码文件

在文件资源管理器标题栏中,选择 **新建文件** 按钮,并将文件命名为 helloworld.cpp

New File title bar button

添加 hello world 源代码

现在粘贴此源代码

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
    vector<string> msg {"Hello", "C++", "World", "from", "VS Code", "and the C++ extension!"};

    for (const string& word : msg)
    {
        cout << word << " ";
    }
    cout << endl;
}

现在按 ⌘S (Windows、Linux Ctrl+S) 保存文件。请注意,您刚刚添加的文件如何在 VS Code 的侧边栏中显示在 **文件资源管理器** 视图 (⇧⌘E (Windows、Linux Ctrl+Shift+E)) 中

File Explorer

您还可以通过在主 **文件** 菜单中选中 **自动保存** 来启用 自动保存,以便自动保存您的文件更改。

最左侧的活动栏允许您打开不同的视图,例如 **搜索**、**源代码管理** 和 **运行**。您将在本教程的后面部分查看 **运行** 视图。您可以在 VS Code 的 用户界面文档 中找到有关其他视图的更多信息。

**注意**:当您保存或打开 C++ 文件时,您可能会收到来自 C/C++ 扩展的关于内部版本可用性的通知,该内部版本允许您测试新功能和修复。您可以通过选择 X(**清除通知**)来忽略此通知。

探索 IntelliSense

在新的 helloworld.cpp 文件中,将鼠标悬停在 vectorstring 上以查看类型信息。在 msg 变量声明之后,开始键入 msg.,就像您在调用成员函数时一样。您应该立即看到一个显示所有成员函数的完成列表,以及一个显示 msg 对象类型信息的窗口

Statement completion IntelliSense

您可以按 Tab 键插入选定的成员;然后,当您添加左括号时,您将看到有关函数所需任何参数的信息。

运行 helloworld.cpp

请记住,C++ 扩展使用您在计算机上安装的 C++ 编译器来构建您的程序。在尝试在 VS Code 中运行和调试 helloworld.cpp 之前,请确保已安装 C++ 编译器。

  1. 打开 helloworld.cpp 以使其成为活动文件。

  2. 按编辑器右上角的播放按钮。

    Screenshot of helloworld.cpp and play button

  3. 从系统上检测到的编译器列表中选择 **C/C++: cl.exe 构建和调试活动文件**。

    C++ debug configuration dropdown

您只需要在第一次运行 helloworld.cpp 时选择编译器。此编译器将被设置为 tasks.json 文件中的“默认”编译器。

  1. 构建成功后,程序的输出将显示在集成的 **终端** 中。

    screenshot of program output

如果您在尝试使用 cl.exe 构建和调试时遇到错误,请确保您已从 Visual Studio 的开发人员命令提示符启动 VS Code,使用 code . 快捷方式。

Error notification when trying to use MSVC without running VS Code from the Developer Command Prompt for VS

第一次运行程序时,C++ 扩展会创建 tasks.json,您可以在项目的 .vscode 文件夹中找到它。tasks.json 存储构建配置。

新的 tasks.json 文件应类似于下面的 JSON 代码

{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "shell",
      "label": "C/C++: cl.exe build active file",
      "command": "cl.exe",
      "args": [
        "/Zi",
        "/EHsc",
        "/Fe:",
        "${fileDirname}\\${fileBasenameNoExtension}.exe",
        "${file}"
      ],
      "problemMatcher": ["$msCompile"],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "detail": "Task generated by Debugger."
    }
  ]
}

注意:您可以在变量参考中了解有关 tasks.json 变量的更多信息。

command 设置指定要运行的程序;在本例中为“cl.exe”。args 数组指定将传递给 cl.exe 的命令行参数。这些参数必须按编译器预期的方式指定。

此任务告诉 C++ 编译器获取活动文件 (${file}),编译它,并在当前目录 (${fileDirname}) 中创建一个可执行文件 (/Fe: 开关),文件名与活动文件相同,但扩展名为 .exe (${fileBasenameNoExtension}.exe),对于我们的示例,结果为 helloworld.exe

label 值是您在任务列表中看到的内容;您可以随意命名它。

detail 值是您在任务列表中作为任务描述看到的内容。强烈建议将此值重命名以将其与类似任务区分开来。

problemMatcher 值选择用于在编译器输出中查找错误和警告的输出解析器。对于 cl.exe,如果您使用 $msCompile 问题匹配器,您将获得最佳效果。

从现在开始,播放按钮将从 tasks.json 中读取以找出如何构建和运行您的程序。您可以在 tasks.json 中定义多个构建任务,并且播放按钮将使用标记为默认的任务。如果您需要更改默认编译器,可以运行 任务:配置默认构建任务。或者,您可以修改 tasks.json 文件并通过替换以下段落来删除默认值

    "group": {
        "kind": "build",
        "isDefault": true
    },

用这个

    "group": "build",

修改 tasks.json

您可以修改您的 tasks.json 以通过使用类似于 "${workspaceFolder}/*.cpp" 而不是 "${file}" 的参数来构建多个 C++ 文件。这将构建您当前文件夹中的所有 .cpp 文件。您还可以通过将 "${fileDirname}\\${fileBasenameNoExtension}.exe" 替换为硬编码文件名 (例如 "${workspaceFolder}\\myProgram.exe") 来修改输出文件名。

调试 helloworld.cpp

要调试您的代码,

  1. 返回到 helloworld.cpp 以使其成为活动文件。
  2. 通过单击编辑器边距或在当前行上使用 F9 来设置断点。 helloworld.cpp 中断点的屏幕截图
  3. 从播放按钮旁边的下拉列表中选择 调试 C/C++ 文件播放按钮下拉列表的屏幕截图
  4. 从系统上检测到的编译器列表中选择 C/C++: cl.exe 构建和调试活动文件(您只需在第一次运行或调试 helloworld.cpp 时选择一次编译器)。 C++ 调试配置下拉列表

播放按钮有两种模式:运行 C/C++ 文件调试 C/C++ 文件。它将默认为最后使用的模式。如果您在播放按钮中看到调试图标,可以选择播放按钮进行调试,而不是选择下拉菜单项。

如果您在尝试使用 cl.exe 构建和调试时遇到错误,请确保您已从 Visual Studio 的开发人员命令提示符启动 VS Code,使用 code . 快捷方式。

Error notification when trying to use MSVC without running VS Code from the Developer Command Prompt for VS

探索调试器

在开始单步执行代码之前,让我们花点时间注意用户界面中的几个变化

  • 集成终端出现在源代码编辑器的底部。在 调试输出 选项卡中,您会看到指示调试器正在运行的输出。

  • 编辑器突出显示您在启动调试器之前设置断点的那一行

    Initial breakpoint

  • 左侧的 运行和调试 视图显示调试信息。您将在本教程后面的部分中看到一个示例。

  • 在代码编辑器的顶部,出现了一个调试控制面板。您可以通过抓住左侧的点将它移动到屏幕上的任何位置。

    Debugging controls

单步执行代码

现在您已准备好开始单步执行代码。

  1. 单击或按调试控制面板中的 单步跳过 图标。

    Step over button

    这将使程序执行前进到 for 循环的第一行,并跳过在创建和初始化 msg 变量时调用的 vectorstring 类中的所有内部函数调用。请注意左侧 变量 窗口中的变化。

    Debugging windows

    在这种情况下,错误是预期的,因为虽然循环的变量名称现在对调试器可见,但该语句尚未执行,因此此时没有可读取的内容。但是,msg 的内容是可见的,因为该语句已完成执行。

  2. 再次按 单步跳过 以前进到此程序中的下一条语句(跳过执行以初始化循环的所有内部代码)。现在,变量 窗口显示有关循环变量的信息。

  3. 再次按 单步跳过 以执行 cout 语句。(请注意,C++ 扩展不会在循环退出之前将任何输出打印到 调试控制台。)

  4. 如果您愿意,可以继续按 单步跳过 直到矢量中的所有单词都打印到控制台。但如果您好奇,请尝试按 单步进入 按钮以单步执行 C++ 标准库中的源代码!

    Breakpoint in gcc standard library header

    要返回到您自己的代码,一种方法是继续按 单步跳过。另一种方法是在您的代码中设置断点,方法是切换到代码编辑器中的 helloworld.cpp 选项卡,将插入点放在循环内的 cout 语句上的任何位置,然后按 F9。左侧的边距中将出现一个红点,指示已在此行上设置了断点。

    Breakpoint in main

    然后按 F5 从标准库头文件中的当前行开始执行。执行将在 cout 上中断。如果您愿意,可以再次按 F9 以切换断点。

设置监视

有时您可能希望在程序执行时跟踪变量的值。您可以通过在变量上设置 监视 来做到这一点。

  1. 将插入点放在循环内。在 监视 窗口中,选择加号,并在文本框中键入 word,这是循环变量的名称。现在,在单步执行循环时查看监视窗口。

    Watch window

  2. 通过在循环之前添加此语句来添加另一个监视:int i = 0;。然后,在循环内部,添加此语句:++i;。现在,在执行上一步操作时为 i 添加一个监视。

  3. 要快速查看执行暂停在断点时任何变量的值,可以使用鼠标指针悬停在该变量上。

    Mouse hover

使用 launch.json 自定义调试

当您使用播放按钮或 F5 进行调试时,C++ 扩展会动态创建调试配置。

在某些情况下,您可能需要自定义调试配置,例如指定在运行时传递给程序的参数。您可以在 launch.json 文件中定义自定义调试配置。

要创建 launch.json,从播放按钮下拉菜单中选择 添加调试配置

Add debug configuration play button menu

然后,您将看到一个包含各种预定义调试配置的下拉菜单。选择 C/C++: cl.exe 构建和调试活动文件

C++ debug configuration dropdown

VS Code 会创建一个 launch.json 文件,它看起来像这样

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "C/C++: cl.exe build and debug active file",
      "type": "cppvsdbg",
      "request": "launch",
      "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${workspaceFolder}",
      "environment": [],
      "externalConsole": false,
      "preLaunchTask": "C/C++: cl.exe build active file"
    }
  ]
}

在上面的 JSON 代码中,program 指定您要调试的程序。在这里,它设置为活动文件文件夹 (${fileDirname}) 和带有 .exe 扩展名的活动文件名 (${fileBasenameNoExtension}.exe),如果 helloworld.cpp 是活动文件,则将为 helloworld.exeargs 属性是在运行时传递给程序的参数数组。

默认情况下,C++ 扩展不会将任何断点添加到您的源代码中,并且 stopAtEntry 值设置为 false

stopAtEntry 值更改为 true 以使调试器在启动调试时在 main 方法上停止。

从现在开始,播放按钮和 F5 在启动程序以进行调试时将从您的 launch.json 文件中读取。

C/C++ 配置

如果您希望对 C/C++ 扩展有更多控制,您可以创建一个 c_cpp_properties.json 文件,这将允许您更改设置,例如编译器路径、包含路径、C++ 标准 (默认值为 C++17) 等等。

您可以通过从命令面板 (⇧⌘P (Windows、Linux Ctrl+Shift+P)) 运行命令 C/C++: 编辑配置 (UI) 来查看 C/C++ 配置 UI。

Command Palette

这将打开 C/C++ 配置 页面。当您在此处进行更改时,VS Code 会将它们写入 .vscode 文件夹中的名为 c_cpp_properties.json 的文件。

Command Palette

Visual Studio Code 将这些设置放在 .vscode\c_cpp_properties.json 中。如果您直接打开该文件,它应该看起来像这样

{
  "configurations": [
    {
      "name": "Win32",
      "includePath": ["${workspaceFolder}/**"],
      "defines": ["_DEBUG", "UNICODE", "_UNICODE"],
      "windowsSdkVersion": "10.0.18362.0",
      "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe",
      "cStandard": "c11",
      "cppStandard": "c++17",
      "intelliSenseMode": "msvc-x64"
    }
  ],
  "version": 4
}

仅当您的程序包含不在您的工作区或标准库路径中的头文件时,才需要添加到 包含路径 数组设置中。

编译器路径

compilerPath 设置是配置中的一个重要设置。扩展程序使用它来推断 C++ 标准库头文件的位置。当扩展程序知道在哪里可以找到这些文件时,它可以提供有用的功能,例如智能完成和 转到定义 导航。

C/C++ 扩展程序尝试根据它在系统中找到的内容,使用默认编译器位置来填充 compilerPath。扩展程序将在几个常见的编译器位置中查找。

compilerPath 搜索顺序为

  • 首先检查 Microsoft Visual C++ 编译器Ope
  • 然后在 Windows 子系统 Linux (WSL) 中查找 g++
  • 然后查找用于 Mingw-w64 的 g++。

如果您安装了 g++ 或 WSL,则可能需要更改 compilerPath 以匹配您项目的首选编译器。对于 Microsoft C++,路径应类似于以下路径,具体取决于您安装的特定版本:“C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.16.27023/bin/Hostx64/x64/cl.exe”。

重复使用 C++ 配置

VS Code 现在配置为使用 Microsoft C++ 编译器。配置适用于当前工作区。要重用配置,只需将 JSON 文件复制到新项目文件夹(工作区)中的 .vscode 文件夹中,并根据需要更改源文件(s) 和可执行文件的名字。

在开发者命令提示符外部运行 VS Code

在某些情况下,无法从 Visual Studio 的开发人员命令提示符 运行 VS Code(例如,在通过 SSH 的远程开发方案中)。在这种情况下,您可以使用以下 tasks.json 配置在构建过程中自动初始化 Visual Studio 的开发人员命令提示符

{
  "version": "2.0.0",
  "windows": {
    "options": {
      "shell": {
        "executable": "cmd.exe",
        "args": [
          "/C",
          // The path to VsDevCmd.bat depends on the version of Visual Studio you have installed.
          "\"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/Common7/Tools/VsDevCmd.bat\"",
          "&&"
        ]
      }
    }
  },
  "tasks": [
    {
      "type": "shell",
      "label": "cl.exe build active file",
      "command": "cl.exe",
      "args": [
        "/Zi",
        "/EHsc",
        "/Fe:",
        "${fileDirname}\\${fileBasenameNoExtension}.exe",
        "${file}"
      ],
      "problemMatcher": ["$msCompile"],
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ]
}

注意VsDevCmd.bat 的路径可能因 Visual Studio 版本或安装路径而异。您可以通过打开命令提示符并运行 dir "\VsDevCmd*" /s 来找到 VsDevCmd.bat 的路径。

故障排除

术语“cl.exe”无法识别

如果您看到错误“术语'cl.exe'不被识别为 cmdlet、函数、脚本文件或可执行程序的名称。”,这通常意味着您是在**Visual Studio 开发人员命令提示符**之外运行 VS Code,并且 VS Code 不知道 cl.exe 编译器的路径。

VS Code 必须从 Visual Studio 开发人员命令提示符启动,或者任务必须配置为在开发人员命令提示符之外运行

您始终可以通过打开新的终端(⌃⇧`(Windows、Linux Ctrl+Shift+`))并输入 'cl' 来验证 cl.exe 是否可供 VS Code 使用,从而检查您是否在开发人员命令提示符的上下文中运行 VS Code。

致命错误 C1034: assert.h: 未设置包含路径

在这种情况下,cl.exe 通过 PATH 环境变量可供 VS Code 使用,但 VS Code 仍需要从**Visual Studio 开发人员命令提示符**启动,或者配置为在开发人员命令提示符之外运行。否则,cl.exe 将无法访问重要的环境变量,例如 INCLUDE

下一步

  • 探索VS Code 用户指南
  • 查看C++ 扩展概述
  • 创建一个新的工作区,将您的 .vscode JSON 文件复制到其中,调整新的工作区路径、程序名称等所需的设置,然后开始编码!