善用 vs 中的錯誤列表和輸出窗口,高效查找 C++ 多工程編譯錯誤


前言

相信,絕大多數小伙伴兒編譯 C++ 或者其它語言的程序都遇到過編譯錯誤。今天簡單總結一下如何使用錯誤列表(Error List)輸出窗口(Output)排查編譯 C++ 代碼產生的編譯錯誤。簡單的錯誤,通過錯誤列表就可以搞定,但是一些復雜的錯誤,只通過錯誤列表很可能是無法解決的,需要借助輸出窗口的幫助。

錯誤列表

錯誤列表可以用來查看編譯時的錯誤、警告等信息。在一條記錄上雙擊,即可切換到對應的代碼行,是我們排查編譯錯誤的好幫手。一般情況下,如果編譯出錯,錯誤列表會自動彈出來,如果沒有彈出來,可以手動打開。

1. 打開方式


我們可以在 View 菜單下找到 Error List,點擊即可打開。對應的快捷鍵是 ctrl + \, e (按住ctrl,然后依次按 \e 即可)。

如果覺得麻煩,還是希望編譯出錯時自動打開錯誤列表的話,我們可以在Tools -> Options-> Projects and Solutions -> General 里設置。

show-error-list-when-compile-fail-setting
show-error-list-when-compile-fail-setting

勾選 Always show Error List if build finishes with errors,可以在編譯完成后,如果有錯誤,則會自動彈出 Error List 窗口。

2. 錯誤列表界面概覽


我們先通過一張圖來了解下錯誤列表。

Error-List-Introduction
Error-List-Introduction

我們發現有 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 編輯框輸入過濾的關鍵字,不過遺憾的是不支持模糊匹配和正則匹配。

下面是我錄制的一個基本的過濾示例,大家可以直接感受下。

Error-List-Filter-Demo
Error-List-Filter-Demo

輸出窗口

輸出窗口不僅可以顯示各種調試信息,還可以顯示編譯的輸出信息,比如編譯錯誤、編譯警告等。有些編譯錯誤,僅通過錯誤列表不能解決,這時候我們需要借助輸出窗口的幫助。

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): 形式的信息,雙擊即可跳轉到對應文件的特定行。

在檢查編譯錯誤時,我們使用的是 BuildBuild Order。其中的 Build Order 尤其有用,可以按順序顯示輸出信息。試想,如果解決方案(Solution)下有很多項目(Project)的話,編譯的時候,項目間的編譯輸出很有可能混到一起,不利於我們排查。通過 Build Order 可以讓輸出有序。然后我們可以按 ctrl + home 鍵跳轉到開頭,然后搜索搜索error,就可以快速找到第一條錯誤信息了。下面是兩個使用輸出窗口排查編譯錯誤的實戰。

實戰

實戰1. 查找頭文件中的編譯錯誤實戰


下圖中的編譯錯誤,全部提示出現在頭文件中。

error-in-header-file
error-in-header-file

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

jump-to-error-line
jump-to-error-line

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

在輸出窗口顯示錯誤-未排序
在輸出窗口顯示錯誤-未排序

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

在輸出窗口顯示錯誤-排序
在輸出窗口顯示錯誤-排序

我們發現 MFCApplication2.cppMFCActiveXControl1.cppMFCActiveXControl2.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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM