在 Visual Studio Code 中使用 Clang
在本教程中,您將在 macOS 上配置 Visual Studio Code 以使用 Clang/LLVM 編譯器和偵錯程式。
配置 VS Code 後,您將在 VS Code 中編譯和除錯 C++ 程式。本教程不講解 Clang 或 C++ 語言。有關這些主題,網路上有很多優秀的資源。
如果您遇到任何問題,請隨時在 VS Code 文件儲存庫中為此教程提交 issue。
先決條件
要成功完成本教程,你必須執行以下步驟
-
安裝 VS Code 的 C++ 擴充套件。您可以透過在“擴充套件”檢視中搜索“C++”來安裝 C/C++ 擴充套件(⇧⌘X (Windows、Linux Ctrl+Shift+X))。

確保 Clang 已安裝
您的 Mac 可能已經安裝了 Clang。要驗證這一點,請開啟 macOS 終端視窗並輸入以下命令:
clang --version
如果未安裝 Clang,請鍵入以下命令安裝命令列開發人員工具,其中包括 Clang:
xcode-select --install
建立 Hello World 應用
在 macOS 終端中,建立一個名為 projects 的空資料夾,用於儲存所有 VS Code 專案,然後建立一個名為 helloworld 的子資料夾,導航到其中,並透過在終端視窗中輸入以下命令在該資料夾中開啟 VS Code:
mkdir projects
cd projects
mkdir helloworld
cd helloworld
code .
code . 命令會在當前工作資料夾中開啟 VS Code,該資料夾將成為您的“工作區”。在整個教程中,將在工作區的 .vscode 資料夾中建立三個檔案:
tasks.json(編譯器構建設定)launch.json(偵錯程式設定)c_cpp_properties.json(編譯器路徑和 IntelliSense 設定)
新增 hello world 原始檔
在“檔案資源管理器”標題欄中,選擇新建檔案按鈕並將檔案命名為 helloworld.cpp。

貼上以下原始碼
#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))中。

您還可以透過選擇“檔案” > “自動儲存”來啟用“自動儲存”,以自動儲存檔案更改。您可以在 VS Code 的 使用者介面文件中找到有關其他檢視的更多資訊。
注意:當你儲存或開啟 C++ 檔案時,你可能會看到來自 C/C++ 擴充套件的關於 Insiders 版本可用性的通知,該版本可讓你測試新功能和修復。你可以透過選擇
X(清除通知)來忽略此通知。
探索 IntelliSense
IntelliSense 是一種工具,透過新增程式碼補全、引數資訊、快速資訊和成員列表等程式碼編輯功能,幫助您更快、更高效地編碼。
要檢視 IntelliSense 的實際效果,請將滑鼠懸停在 vector 或 string 上以檢視其型別資訊。如果您在第 10 行鍵入 msg.,您將看到一個推薦成員函式的補全列表,所有這些都由 IntelliSense 生成。

您可以按 Tab 鍵插入選定的成員。然後,當您新增開括號時,將顯示有關函式所需引數的資訊。
如果 IntelliSense 尚未配置,請開啟命令面板(⇧⌘P (Windows、Linux Ctrl+Shift+P)),然後輸入選擇 IntelliSense 配置。從編譯器下拉列表中,選擇 使用 clang++ 進行配置。有關更多資訊,請參閱 IntelliSense 配置文件。
執行 helloworld.cpp
請記住,C++ 擴充套件使用您在計算機上安裝的 C++ 編譯器來構建您的程式。在嘗試在 VS Code 中執行和除錯 helloworld.cpp 之前,請確保您已安裝 C++ 編譯器,例如 Clang。
-
開啟
helloworld.cpp,使其成為活動檔案。 -
單擊編輯器右上角的播放按鈕。

-
從系統中檢測到的編譯器列表中選擇“C/C++: clang++ 構建和除錯活動檔案”。

只有在首次執行 helloworld.cpp 時才會要求您選擇編譯器。此編譯器是 tasks.json 檔案中設定的“預設”編譯器。
-
構建成功後,程式的輸出將顯示在整合的“除錯控制檯”中。

恭喜!您剛剛在 VS Code 中運行了第一個 C++ 程式!
理解 tasks.json
首次執行程式時,C++ 擴充套件會建立 tasks.json 檔案,該檔案位於專案資料夾的 .vscode 中。tasks.json 儲存構建配置。
以下是 macOS 上的 tasks.json 檔案示例:
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: clang++ build active file",
"command": "/usr/bin/clang++",
"args": [
"-fcolor-diagnostics",
"-fansi-escape-codes",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": ["$gcc"],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
注意:你可以在變數參考中瞭解有關
tasks.json變數的更多資訊。
command 設定指定要執行的程式。在這種情況下,它是 clang++。
args 陣列指定傳遞給 clang++ 的命令列引數。這些引數必須按照編譯器期望的順序指定。
此任務指示 C++ 編譯器接受活動檔案 (${file}),對其進行編譯,並在當前目錄 (${fileDirname}) 中建立輸出檔案(使用 -o 開關),該檔名與活動檔名相同,但不帶副檔名(${fileBasenameNoExtension})。此過程將建立 helloworld。
label 值是您在任務列表中看到的內容,它基於您的個人偏好。
detail 值是任務列表中任務的描述。更新此字串以將其與類似任務區分開。
problemMatcher 值選擇用於在編譯器輸出中查詢錯誤和警告的輸出解析器。對於 clang++,$gcc problemMatcher 可產生最佳結果。
從現在開始,播放按鈕始終從 tasks.json 讀取以確定如何構建和執行您的程式。您可以在 tasks.json 中定義多個構建任務,其中標記為預設的任務是播放按鈕使用的任務。如果您需要更改預設編譯器,可以在命令面板中執行“任務: 配置預設構建任務”。或者,您可以修改 tasks.json 檔案並透過替換此段來刪除預設值:
"group": {
"kind": "build",
"isDefault": true
},
替換為
"group": "build",
修改 tasks.json
您可以透過使用類似 "${workspaceFolder}/*.cpp" 的引數而不是 "${file}" 來修改 tasks.json 以構建多個 C++ 檔案。這會構建當前資料夾中的所有 .cpp 檔案。您還可以透過將 "${fileDirname}/${fileBasenameNoExtension}" 替換為硬編碼檔名(例如 "${workspaceFolder}/myProgram.out")來修改輸出檔名。
除錯 helloworld.cpp
要除錯你的程式碼,
-
回到
helloworld.cpp,使其成為活動檔案。 -
透過單擊編輯器邊距或使用 F9 在當前行設定斷點。

-
從播放按鈕旁邊的下拉列表中,選擇“除錯 C/C++ 檔案”。

-
從系統中檢測到的編譯器列表中選擇“C/C++: clang++ 構建和除錯活動檔案”(只有在首次執行或除錯
helloworld.cpp時才會要求您選擇編譯器)。
-
您將看到任務執行並在“終端”視窗中列印輸出。

播放按鈕有兩種模式:“執行 C/C++ 檔案”和“除錯 C/C++ 檔案”。預設是最後使用的模式。如果您在播放按鈕上看到除錯圖示,則可以選擇播放按鈕進行除錯,而不是選擇下拉選單項。
探索偵錯程式
在開始單步除錯程式碼之前,我們花點時間注意使用者介面中的幾處變化
-
整合終端出現在原始碼編輯器的底部。在“除錯控制檯”選項卡中,您將看到指示偵錯程式已啟動並正在執行的輸出。
-
編輯器會高亮顯示你在啟動偵錯程式之前設定斷點的行

-
活動欄中的“執行和除錯”檢視顯示除錯資訊。
-
程式碼編輯器頂部會出現一個除錯控制面板。你可以透過抓取左側的點來在螢幕上移動它。

單步除錯程式碼
現在你已準備好開始單步除錯程式碼。
-
選擇除錯控制面板中的“跳過”圖示,以便突出顯示
for (const string& word : msg)語句。
跳過命令會跳過建立和初始化
msg變數時呼叫的vector和string類中的所有內部函式呼叫。請注意“變數”視窗中的變化。msg的內容可見,因為該語句已完成。 -
再次按“跳過”前進到下一條語句(跳過初始化迴圈要執行的所有內部程式碼)。現在,“變數”視窗顯示有關迴圈變數的資訊。
-
再次按“跳過”以執行
cout語句。 -
如果你願意,可以繼續按單步跳過,直到向量中的所有單詞都列印到控制檯。但如果你好奇,可以嘗試按單步進入按鈕來單步執行 C++ 標準庫中的原始碼!
設定監視
您可能希望在程式執行過程中跟蹤變數的值。您可以透過為變數設定“監視”來實現此目的。
-
在“監視”視窗中,選擇加號,然後在文字框中鍵入
word。這是迴圈變數的名稱。現在,在逐行執行迴圈時,檢視“監視”視窗。
注意:監視變數的值僅在程式執行位於該變數的作用域內時才可用。例如,對於迴圈變數,該值僅在程式執行迴圈時才可用。
-
透過在迴圈前新增此語句來新增另一個監視:
int i = 0;。然後,在迴圈內部新增此語句:++i;。現在,像上一步一樣為i新增監視。 -
當程式執行暫停時,您可以透過將滑鼠指標懸停在任何變數上來快速檢視其值。

使用 launch.json 自定義除錯
當你使用播放按鈕或 F5 進行除錯時,C++ 擴充套件會即時建立一個動態除錯配置。
在某些情況下,你可能希望自定義除錯配置,例如指定在執行時傳遞給程式的引數。你可以在 launch.json 檔案中定義自定義除錯配置。
要建立 launch.json,請從播放按鈕下拉選單中選擇新增除錯配置。

然後,您將看到一個下拉列表,其中包含各種預定義的除錯配置。選擇“C/C++: clang++ 構建和除錯活動檔案”。 
VS Code 建立一個 launch.json 檔案,它看起來像這樣
{
"configurations": [
{
"name": "C/C++: clang++ build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb",
"preLaunchTask": "C/C++: clang++ build active file"
}
],
"version": "2.0.0"
}
program 設定指定您要除錯的程式。這裡設定為活動檔案資料夾 ${fileDirname} 和活動檔名 ${fileBasenameNoExtension},如果 helloworld.cpp 是活動檔案,則為 helloworld。args 屬性是要在執行時傳遞給程式的引數陣列。
預設情況下,C++ 擴充套件不會向原始碼新增任何斷點,並且 stopAtEntry 值設定為 false。
將 stopAtEntry 值更改為 true,以便在開始除錯時讓偵錯程式在 main 方法處停止。
確保 preLaunchTask 值與 tasks.json 檔案中的構建任務的 label 匹配。
從現在開始,播放按鈕和 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。

這將開啟“C/C++ 配置”頁面。

Visual Studio Code 將這些設定放在 .vscode/c_cpp_properties.json 中。如果你直接開啟該檔案,它應該看起來像這樣
{
"configurations": [
{
"name": "Mac",
"includePath": ["${workspaceFolder}/**"],
"defines": [],
"macFrameworkPath": [
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "macos-clang-arm64"
}
],
"version": 4
}
只有當您的程式包含工作區或標準庫路徑中不存在的標頭檔案時,才需要修改“包含路徑”設定。
編譯器路徑
該擴充套件使用 compilerPath 設定來推斷 C++ 標準庫標頭檔案的路徑。當擴充套件知道在哪裡可以找到這些檔案時,它就可以提供智慧補全和“轉到定義”導航等功能。
C/C++ 擴充套件會嘗試根據它在系統上找到的內容,將 compilerPath 填充為預設編譯器位置。compilerPath 的搜尋順序是:
- 您的 PATH 中已知編譯器的名稱。編譯器在列表中的出現順序取決於您的 PATH。
- 然後會搜尋硬編碼的 Xcode 路徑,例如
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/。
有關更多資訊,請參閱 IntelliSense 配置文件。
Mac 框架路徑
在“C/C++ 配置”螢幕上,向下滾動並展開“高階設定”,並確保“Mac 框架路徑”指向系統標頭檔案。例如:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks。
故障排除
編譯器和連結錯誤
錯誤的最常見原因(例如 undefined _main 或 attempting to link with file built for unknown-unsupported file format 等)發生在您啟動構建或除錯時 helloworld.cpp 不是活動檔案。這是因為編譯器試圖編譯非原始碼的內容,例如您的 launch.json、tasks.json 或 c_cpp_properties.json 檔案。
如果您看到有關“C++11 擴充套件”的構建錯誤,您可能尚未更新 tasks.json 構建任務以使用 clang++ 引數 --std=c++17。預設情況下,clang++ 使用 C++98 標準,該標準不支援 helloworld.cpp 中使用的初始化。請確保用 執行 helloworld.cpp 部分中提供的程式碼塊替換 tasks.json 檔案的全部內容。
終端無法啟動用於輸入
在 macOS Catalina 及更高版本上,您可能會遇到即使設定了 "externalConsole": true 也無法輸入的問題。會開啟一個終端視窗,但實際上不允許您鍵入任何輸入。
該問題目前正在 #5079 中跟蹤。
解決方法是讓 VS Code 啟動一次終端。您可以透過在 tasks.json 中新增並執行以下任務來實現:
{
"label": "Open Terminal",
"type": "shell",
"command": "osascript -e 'tell application \"Terminal\"\ndo script \"echo hello\"\nend tell'",
"problemMatcher": []
}
您可以使用“終端”>“執行任務...”並選擇“開啟終端”來執行此特定任務。
接受許可權請求後,外部控制檯應在除錯時出現。
後續步驟
- 探索 VS Code 使用者指南。
- 檢視 C++ 擴充套件概述。
- 建立一個新的工作區,將你的 .json 檔案複製到其中,調整新工作區路徑、程式名稱等必要的設定,然後開始編碼!