前言
相信,絕大多數小伙伴兒編譯 C++
或者其它語言的程序都遇到過編譯錯誤。今天簡單總結一下如何使用錯誤列表(Error List)和輸出窗口(Output)排查編譯 C++
代碼產生的編譯錯誤。簡單的錯誤,通過錯誤列表就可以搞定,但是一些復雜的錯誤,只通過錯誤列表很可能是無法解決的,需要借助輸出窗口的幫助。
錯誤列表
錯誤列表可以用來查看編譯時的錯誤、警告等信息。在一條記錄上雙擊,即可切換到對應的代碼行,是我們排查編譯錯誤的好幫手。一般情況下,如果編譯出錯,錯誤列表會自動彈出來,如果沒有彈出來,可以手動打開。
1. 打開方式
我們可以在 View
菜單下找到 Error List
,點擊即可打開。對應的快捷鍵是 ctrl + \, e
(按住ctrl
,然后依次按 \
和 e
即可)。
如果覺得麻煩,還是希望編譯出錯時自動打開錯誤列表的話,我們可以在Tools -> Options-> Projects and Solutions -> General
里設置。

勾選 Always show Error List if build finishes with errors
,可以在編譯完成后,如果有錯誤,則會自動彈出 Error List
窗口。
2. 錯誤列表界面概覽
我們先通過一張圖來了解下錯誤列表。

我們發現有 7 列,每一列都有它的作用。
-
第 1 列:
Category
,以圖標的形式表示信息的類型。大紅叉
是真正的錯誤。小紅叉
一般是智能提示給出的,不是真正意義上的錯誤。對是否能成功編譯沒有影響。黃色三角形+嘆號
一般是警告信息。圓形+嘆號
一般是提示信息。
-
第 2 列:
Default Order
,提示信息的編號。我沒關注過。 -
第 3 列:
Description
,簡要描述,可以粗略判斷下錯誤。 -
第 4 列:
File
,文件。如果是頭文件的話,有可能需要排查包含的此頭文件的源文件。 -
第 5 列:
Line
,行號。 -
第 6 列:
Column
,列號。 -
第 7 列:
Project
,相關的工程。如果項目里有多個工程,可以根據此列進行一個初步的過濾。
如果不想顯示 Intellisense Error
,可以右鍵,取消勾選 Show IntelliSense Errors
。
可以根據任意一列排序(雙擊對應列標題即可排序),或者 右鍵
,Sort By
選擇需要排序的列。
可以顯示或者隱藏任意一列,右鍵
, Show Columns
選擇需要顯示/隱藏的列即可。
3. 過濾
Error List
是支持過濾的,善用過濾可以幫我們快速找到關心的信息。
點擊左側漏洞形狀的按鈕
旁邊的下拉按鈕,可以看到三種選項:
-
Open Documents
:只保留與當前所有打開的文檔相關的信息。 -
Current Project
:只保留所有屬於當前工程的信息。 -
Curent Document
:只保留與當前文檔相關的信息。
可以在右側的 Search Error List
編輯框輸入過濾的關鍵字,不過遺憾的是不支持模糊匹配和正則匹配。
下面是我錄制的一個基本的過濾示例,大家可以直接感受下。

輸出窗口
輸出窗口不僅可以顯示各種調試信息,還可以顯示編譯的輸出信息,比如編譯錯誤、編譯警告等。有些編譯錯誤,僅通過錯誤列表不能解決,這時候我們需要借助輸出窗口的幫助。
1. 打開方式
我們可以在 View
菜單下找到 Output
,點擊即可打開。對應的快捷鍵是 ctrl + alt + o
。
如果希望在編譯時自動打開輸出窗口的話,我們可以在Tools -> Options-> Projects and Solutions -> General
里設置。
勾選 Show Output window when build starts
可以在編譯開始的時候自動彈出輸出窗口。可以參考錯誤列表打開方式的截圖。
2. 簡要介紹
輸出窗口用法比較簡單,鼠標移動到對應的按鈕上就有懸浮提示,不一一介紹了。我們可以根據 Show output from:
選項過濾不同來源的信息。我見過以下幾種:
-
Build
:編譯產生的信息。 -
Build Order
:編譯產生的信息,按順序顯示。 -
Debug
:調試輸出信息。如果被調試的進程通過OutputDebugString()
或等價的API
輸出調試信息,則會顯示在此分類下。 -
Source Control - Git
:來自版本管理系統Git
的信息,vs
檢測到當前有代碼被Git
管理,則會出現此分類。 -
Source Control - Team Foundation
:來自版本管理系統Team Foundation
的信息,如果vs
檢測到當前代碼被TFS
管理,則會出現此分類。 -
Solution
:工程加載類消息。如果某個工程加載失敗,會在該分類下顯示錯誤提示。
**說明:**如果某一行包含 path\to\file(line):
形式的信息,雙擊即可跳轉到對應文件的特定行。
在檢查編譯錯誤時,我們使用的是 Build
和 Build Order
。其中的 Build Order
尤其有用,可以按順序顯示輸出信息。試想,如果解決方案(Solution
)下有很多項目(Project
)的話,編譯的時候,項目間的編譯輸出很有可能混到一起,不利於我們排查。通過 Build Order
可以讓輸出有序。然后我們可以按 ctrl + home
鍵跳轉到開頭,然后搜索搜索error
,就可以快速找到第一條錯誤信息了。下面是兩個使用輸出窗口排查編譯錯誤的實戰。
實戰
實戰1. 查找頭文件中的編譯錯誤實戰
下圖中的編譯錯誤,全部提示出現在頭文件中。

我們雙擊后會跳轉到頭文件。

除了知道錯誤發生在第 6 行,我們並不能得到更多有用信息了。我們需要找到是哪個源文件包含了這個頭文件,到源文件里進一步查找原因。這時候我們需要切換到輸出窗口了。

從上圖中我們看不出來到底是哪個源文件包含了出問題的頭文件。我們需要切換到 Build Order
,如下圖:

我們發現 MFCApplication2.cpp
,MFCActiveXControl1.cpp
和 MFCActiveXControl2.cpp
包含了 d4d.h
。我們可以進行下一步的排查了,因為這個問題比較有意思,具體排查過程會單獨寫一篇文章。
實戰2. 查找名字解析錯誤實戰
下圖是嘗試匹配重載函數失敗時,錯誤列表給出的錯誤提示。

從提示中我們得知,在 4
個重載函數中沒有一個能匹配給定的兩個參數。但是編譯器具體嘗試匹配了哪些函數呢?我們無法從錯誤列表得知。不過我們可以通過輸出窗口查看編譯器具體嘗試匹配了哪些函數,如下圖:

我們可以發現,在我們提供的四個重載函數中,沒有一個函數可以完全匹配給定的兩個參數,編譯器就懵逼了,不知道應該選擇哪個了,所以就報錯了。
本例只是一個超級簡單的例子,並不能很好的突出輸出窗口的作用。一般涉及模板的編譯錯誤會有一大串。這時候通過輸出窗口查看具體的匹配過程就很重要了。
總結
- 善用錯誤列表的過濾功能,可以幫我們快速找到關心的信息。
- 輸出窗口中的
Build Order
可以讓輸出有序,在查找多工程編譯輸出的時候,有助於我們快速找到相關代碼。 - 錯誤列表 + 輸出窗口 + 一些設置 基本上可以解決絕大多數編譯錯誤。
參考資料
https://docs.microsoft.com/en-us/visualstudio/ide/reference/error-list-window?view=vs-2019
https://docs.microsoft.com/en-us/visualstudio/ide/reference/output-window?view=vs-2019