在 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::string
和 std::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
上方,以顯示快速動作功能表。 點選取燈泡 (或選擇[ 顯示潛在修正連結 ] 以檢視與未使用檔案相關的動作:
新增可轉移使用的標頭
我們可以選擇移除未使用的頭檔,但這會中斷程式代碼,因為 <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::string
。std::cout
此程序代碼不再脆弱,因為它不相依 myHeader.h
於包含其他必要標頭。
最佳做法
請勿移除看似未使用頭文件的內容,而不先新增間接包含的頭檔。 這是因為您的程式代碼可能依賴間接包含在未使用的頭檔中。 先新增可轉移使用的標頭。 然後,當您移除未使用的標頭時,由於已移除頭文件間接包含的頭文件遺失,所以不會收到編譯錯誤。
若要這樣做,其中一種方法是設定 [新增遺漏] 的 [包含清除] 設定 [建議] 的建議層級 (工具>選項>文本編輯器>C/C++>Code 清除]。 此外,將 [移除未使用的包含建議] 的建議層級 設定為 [建議]。 接下來:
- 在錯誤清單中,確定篩選條件設定為 [建置 + IntelliSense]。
- 尋找「來自 #include x 的內容用於此檔案中並暫時包含」的實例。
- 將游標暫留在具有建議的行上。 從燈泡下拉式清單中,選取 [ 新增所有可轉移使用的包含]。
- 重複專案中的這些步驟,直到解決所有有關可轉移包含的建議為止。
- 拿掉未使用的 include:在錯誤清單中,尋找 「#include x 未用於此檔案」的實例。
- 將游標暫留在未使用的標頭上。 從燈泡下拉式清單中,選取 [移除所有未使用的專案]。
- 重複專案中的這些步驟,直到解決所有 Include Cleanup 建議為止。
在此簡短概觀中,您已瞭解 Include Cleanup 如何協助您移除未使用的標頭,以及新增間接包含的標頭。 這可協助您保持程式代碼乾淨、可能更快速地建置,並減少程式碼的脆性。
另請參閱
在 Visual Studio 中設定 C/C++ Include Cleanup
Include Cleanup 訊息