共用方式為


在 Visual Studio 中清理 C/C++ 的 include

從 Visual Studio 17.8 Preview 1 開始,Visual Studio 提供 #include 清除功能,以下列方式改善程式代碼的品質:

  • 僅因為需要頭檔會由另一個頭文件間接包含,因此提供新增程式碼的頭檔。
  • 拿掉未使用的標頭檔 -- 改善建置時間和程式碼清潔的供應專案。

Include Cleanup 預設為開啟。 若要瞭解如何進行設定,請參閱 在Visual Studio中設定 C/C++ Include Cleanup。

直接與間接標頭

首先,一些術語:

  • 直接標頭是您明確 #include 在程序代碼中的標頭。
  • 間接標頭是您未明確 #include表示的標頭。 相反地,您直接包含的頭檔會包含它。 我們也表示包含 transitively間接標頭。

包含清除會分析您的程序代碼,並判斷未使用哪些標頭,以及哪些標頭會間接包含。 請考慮下列頭檔:

// myHeader.h

#include <string>
#include <iostream>

void myFunc()
{
    std::string s = "myFunc()\n";
    std::cout << s;
}

以及使用它的程式:

// myProgram.cpp
#include "myHeader.h"

int main()
{
    std::string s = "main()"; // string is indirectly included by myHeader.h
    std::cout << s; // cout is indirectly included by myHeader.h
    myFunc();
}

myHeader.h 是直接標頭,因為 myProgram.cpp 明確包含它。 myHeader.h 包含 <string><iostream>,因此這些是間接標頭。

問題是 myProgram.cpp 使用 std::stringstd::cout,但不直接包含定義它們的標頭。 此程式代碼會發生編譯,因為 myHeader.h 包含這些標頭。 此程式代碼很脆弱,因為如果 myHeader.h 曾經停止包含其中一個程序代碼, myProgram.cpp 就不會再編譯。

根據C++指導方針,最好明確包含所有相依性的標頭,讓您的程式代碼不受頭文件變更所造成的脆弱。 如需詳細資訊,請參閱 C++ Core Guidelines SF.10

包含清除會分析您的程式代碼,以識別未使用和間接包含的標頭。 它會根據 Visual Studio 中設定 C++ #include 工具中所述的設定提供意見反應。 意見反應可以是錯誤清單警告、建議等形式。如需 Include Cleanup 所提供意見反應的詳細資訊,請參閱 包含清除訊息

未使用的標頭

隨著程式代碼的發展,您可能不再需要一些頭檔。 這很難在複雜的項目中追蹤。 一段時間后,您的組建可能需要更長的時間,因為編譯程式正在處理不必要的頭檔。 包含清除可協助您尋找和移除未使用的標頭。 例如,如果在 myFunc()myProgram.cpp加上批注,該怎麼辦:

// myProgram.cpp
#include "myHeader.h"

int main()
{
    std::string s = "main()"; // string is indirectly included from myHeader.h
    std::cout << s; // cout is indirectly included from myHeader.h
    // myFunc(); // directly included from myHeader.h
}

在下列螢幕快照中,#include "myHeader.h"是暗灰色的(在 Visual Studio 中設定C++#include 工具中所述的設定),因為它不會因為已批注而使用myFunc()

將游標暫留在暗灰色 #include 上方,以顯示快速動作功能表。 點選取燈泡 (或選擇[ 顯示潛在修正連結 ] 以檢視與未使用檔案相關的動作:

顯示三個重構選項:Remove # include myHeader.h、移除所有未使用的 include,以及新增所有可轉移使用的和移除所有未使用的 # include。

新增可轉移使用的標頭

我們可以選擇移除未使用的頭檔,但這會中斷程式代碼,因為 <string><iostream> 是透過 myheader.h間接包含。

相反地,我們可以選擇 [ 新增所有可轉移使用的] 並移除所有未使用 #includes。 這會移除未使用的標頭 myHeader.h,但也會新增透過 間接包含 myHeader.h的任何標頭。 在此情況下,結果會將 和 #include <iostream> 新增#include <string>myProgram.cpp,並移除 #include "myHeader.h"

// myProgram.cpp
#include <iostream>
#include <string>

int main()
{
    std::string s = "main()"; // string is directly included from <string>
    std::cout << s; // cout is directly included from <string>
    // MyFunc();
}

此工具不會更新批注,但您可以看到程式代碼現在使用 且直接使用std::stringstd::cout 此程序代碼不再脆弱,因為它不相依 myHeader.h 於包含其他必要標頭。

最佳做法

請勿移除看似未使用頭文件的內容,而不先新增間接包含的頭檔。 這是因為您的程式代碼可能依賴間接包含在未使用的頭檔中。 先新增可轉移使用的標頭。 然後,當您移除未使用的標頭時,由於已移除頭文件間接包含的頭文件遺失,所以不會收到編譯錯誤。

若要這樣做,其中一種方法是設定 [新增遺漏] 的 [包含清除] 設定 [建議] 的建議層級 工具>選項>文本編輯器>C/C++>Code 清除]。 此外,將 [移除未使用的包含建議] 的建議層級 設定為 [建議]。 接下來:

  1. 在錯誤清單中,確定篩選條件設定為 [建置 + IntelliSense]。
  2. 尋找「來自 #include x 的內容用於此檔案中並暫時包含」的實例。
  3. 將游標暫留在具有建議的行上。 從燈泡下拉式清單中,選取 [ 新增所有可轉移使用的包含]。
  4. 重複專案中的這些步驟,直到解決所有有關可轉移包含的建議為止。
  5. 拿掉未使用的 include:在錯誤清單中,尋找 「#include x 未用於此檔案」的實例。
  6. 將游標暫留在未使用的標頭上。 從燈泡下拉式清單中,選取 [移除所有未使用的專案]。
  7. 重複專案中的這些步驟,直到解決所有 Include Cleanup 建議為止。

在此簡短概觀中,您已瞭解 Include Cleanup 如何協助您移除未使用的標頭,以及新增間接包含的標頭。 這可協助您保持程式代碼乾淨、可能更快速地建置,並減少程式碼的脆性。

另請參閱

在 Visual Studio 中設定 C/C++ Include Cleanup
Include Cleanup 訊息