使用 C++ Core Guidelines 檢查工具

C++ 核心指導方針是一組可攜式指導方針、規則,以及 C++ 專家和設計工具在 C++ 中撰寫程式代碼的最佳做法。 Visual Studio 目前支援這些規則的子集,做為其 C++ 程式代碼分析工具的一部分。 根據預設,核心指導方針檢查程式會安裝在Visual Studio 2017和Visual Studio 2019中。 它們可作為 Visual Studio 2015 的 NuGet 套件。

C++ 核心指導方針專案

由 Bjarne Stroustrup 和其他專案所建立,C++ 核心指導方針是安全且有效地使用新式 C++ 的指南。 指導方針強調靜態類型安全性和資源安全。 他們識別出消除或最小化語言最容易出錯部分的方法。 它們也會建議如何讓您的程式代碼更簡單、更可靠,並具有更佳的效能。 這些指導方針是由標準 C++ 基礎所維護。 若要深入瞭解,請參閱檔、C++ 核心指導方針,以及存取 GitHub 上的 C++ 核心指導方針文件項目檔。

在程式代碼分析中啟用 C++ 核心檢查指導方針

C++ 核心檢查規則的子集包含在 Microsoft Native Recommended 規則集中。 這是啟用程式代碼分析時預設執行的規則集。

若要在您的項目上啟用程式代碼分析

  1. 開啟專案的 [ 屬性頁] 對話框。

  2. 選取 [組態屬性程序代碼分析]>屬性頁。

  3. 選取 [ 在建置 時啟用程式代碼分析] 複選框。

Property page for Code Analysis General settings.

若要啟用更多核心檢查規則,請開啟下拉式清單,然後選擇您想要包含的規則集:

Dropdown for additional C++ Core Check rule sets.

C++ 核心檢查規則的子集包含在 Microsoft Native Recommended 規則集中。 這是啟用 Microsoft 程式代碼分析時預設執行的規則集。

若要在您的項目上啟用程式代碼分析:

  1. 開啟專案的 [ 屬性頁] 對話框。

  2. 選取 [組態屬性程序代碼分析]>屬性頁。

  3. 設定 [ 在建置 時啟用程式代碼分析] 和 [啟用 Microsoft 程式代碼分析 ] 屬性。

您也可以選擇執行所有支援的 C++ 核心檢查規則,或選取您自己的子集來執行:

啟用更多核心檢查規則

  1. 開啟專案的 [ 屬性頁] 對話框。

  2. 選取 [組態屬性程序代碼分析>Microsoft]>屬性頁。

  3. 開啟 [作用中 規則] 下拉式清單,然後選取 [ 選擇多個規則集]。

  4. 在 [ 新增或移除規則集 ] 對話框中,選擇您要包含的規則集。

範例

以下是 C++ 核心檢查規則可找到的一些問題範例:

// CoreCheckExample.cpp
// Add CppCoreCheck package and enable code analysis in build for warnings.

int main()
{
    int arr[10];           // warning C26494
    int* p = arr;          // warning C26485

    [[gsl::suppress(bounds.1)]] // This attribute suppresses Bounds rule #1
    {
        int* q = p + 1;    // warning C26481 (suppressed)
        p = q++;           // warning C26481 (suppressed)
    }

    return 0;
}

此範例示範 C++ 核心檢查規則可找到的一些警告:

  • C26494 是規則 Type.5:永遠初始化物件。

  • C26485 是規則Bounds.3:沒有數位對指標的衰變。

  • C26481 是規則 Bounds.1:請勿使用指標算術。 請改用 span

安裝並啟用 C++ Core 檢查程式代碼分析規則集,然後編譯此程式碼。 程式代碼分析會輸出前兩個警告,並隱藏第三個警告。 以下是 Visual Studio 2015 中範例程式代碼的組建輸出:

1>------ Build started: Project: CoreCheckExample, Configuration: Debug Win32 ------
1>  CoreCheckExample.cpp
1>  CoreCheckExample.vcxproj -> C:\Users\username\documents\visual studio 2015\Projects\CoreCheckExample\Debug\CoreCheckExample.exe
1>  CoreCheckExample.vcxproj -> C:\Users\username\documents\visual studio 2015\Projects\CoreCheckExample\Debug\CoreCheckExample.pdb (Full PDB)
c:\users\username\documents\visual studio 2015\projects\corecheckexample\corecheckexample\corecheckexample.cpp(6): warning C26494: Variable 'arr' is uninitialized. Always initialize an object. (type.5: http://go.microsoft.com/fwlink/p/?LinkID=620421)
c:\users\username\documents\visual studio 2015\projects\corecheckexample\corecheckexample\corecheckexample.cpp(7): warning C26485: Expression 'arr': No array to pointer decay. (bounds.3: http://go.microsoft.com/fwlink/p/?LinkID=620415)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

C++ 核心指導方針可協助您撰寫更好且更安全的程序代碼。 不過,您可能會發現不應該套用規則或配置檔的實例。 直接在程式代碼中隱藏它很容易。 您可以使用 [[gsl::suppress]] 屬性來防止 C++ Core Check 偵測並報告下列程式代碼區塊中任何違反規則的行為。 您可以標記個別語句以隱藏特定規則。 您甚至可以藉由撰寫 [[gsl::suppress(bounds)]] 來隱藏整個界限配置檔,而不包含特定的規則編號。

支援的規則集

當新的規則新增至 C++ 核心指導方針檢查程式時,針對預先存在的程式代碼所產生的警告數目可能會增加。 您可以使用預先定義的規則集來篩選要啟用的規則種類。 您可以在 Visual Studio C++ 核心檢查參考下找到大部分規則的 參考文章。

  • 算術規則:偵測算術 溢位帶正負號的運算位操作的規則。15.6

  • 界限規則:強制執行 C++ 核心指導方針的界限配置檔。15.3

  • 類別規則:一些著重於適當使用特殊成員函式和虛擬規格的規則。 它們是針對 類別和類別階層建議的檢查子集。15.5

  • 並行規則:單一規則,會攔截不正確的防護物件宣告。 如需詳細資訊,請參閱 與並行相關的指導方針。15.5

  • Const 規則:從 C++ 核心指導方針強制執行 const 相關檢查。15.3

  • 宣告規則:一些來自介面指導方針的規則,著重於如何宣告全域變數。15.5

  • 列舉規則:這些規則會強制執行 C++ 核心指導方針中的列舉相關檢查。16.3

  • 實驗性規則 這些是實驗性 C++ 核心檢查規則,這些規則很有用,但尚未準備好供日常使用。 試試看並提供 意見反應16.0

  • 函式規則:兩項檢查可協助採用 noexcept 規範。 它們是清楚函式設計和實作的指導方針的一部分。15.5

  • GSL 規則:這些規則會從 C++ 核心指導方針強制執行與 指導方針支持連結庫相關的檢查。15.7

  • 存留期規則:這些規則會強制執行 C++ 核心指導方針的存留期配置檔。15.7

  • 擁有者指標規則:從 C++ 核心指導方針強制執行與擁有者<T> 相關的資源管理檢查。15.3

  • 原始指標規則:從 C++ 核心指導方針強制執行與原始指標相關的資源管理檢查。15.3

  • 共用指標規則:這是資源管理指導方針強制執行的一部分。15.5 我們已新增一些特定規則,以瞭解如何將共用指標傳遞至函式或在本機使用。

  • STL 規則:這些規則會從 C++ 核心指導方針強制執行與 C++ 標準連結庫 (STL) 相關的檢查。15.7

  • 樣式規則:一個簡單但重要的檢查,禁止使用 goto15.5 這是改善您在 C++ 中撰寫程式代碼樣式和使用運算式和語句的第一個步驟。

  • 類型規則:強制執行 C++ 核心指導方針的類型配置檔。15.3

  • 唯一指標規則:強制執行 與 C++ 核心指導方針中具有唯一指標語意之類型相關的資源管理檢查。15.3

  • C++ 核心檢查規則:此規則集包含 C++ 核心指導方針中目前實作的所有檢查,但實驗性規則除外。

15.3 這些規則首先出現在Visual Studio 2017 15.3版
15.5 這些規則首先出現在Visual Studio 2017 15.5版
15.6 這些規則首先出現在Visual Studio 2017 15.6版
15.7 這些規則首先出現在Visual Studio 2017 15.7版
16.0 這些規則會先出現在Visual Studio 2019 16.0版
16.3 這些規則會先出現在Visual Studio 2019 16.3版

您可以選擇將警告限制為只有一或幾個群組。 原生最小值原生建議的規則集包括 C++ 核心檢查規則和其他 PREfast 檢查。

若要查看可用的規則集,請開啟 [ 項目屬性] 對話方塊。 在 [屬性頁] 對話框中,選取 [組態屬性程序代碼分析>一般]>屬性頁。 然後,在 [規則集] 下拉式方塊中開啟下拉式清單,以查看可用的規則集。 若要建置規則集的自定義組合,請選取 [ 選擇多個規則集]。 [ 新增或移除規則集 ] 對話框會列出您可以選擇的規則。 如需在 Visual Studio 中使用規則集的詳細資訊,請參閱 使用規則集指定要執行的 C++ 規則。

若要查看可用的規則集,請開啟 [ 項目屬性] 對話方塊。 在 [屬性頁] 對話框中,選取 [組態屬性程序代碼分析>Microsoft]>屬性頁。 然後,在 [ 使用中規則 ] 下拉式方塊中開啟下拉式清單,以查看可用的規則集。 若要建置規則集的自定義組合,請選取 [ 選擇多個規則集]。 [ 新增或移除規則集 ] 對話框會列出您可以選擇的規則。 如需在 Visual Studio 中使用規則集的詳細資訊,請參閱 使用規則集指定要執行的 C++ 規則。

巨集

C++ 核心指導方針檢查程式隨附頭檔,其會定義宏,讓您更輕鬆地在程式代碼中隱藏整個類別的警告:

ALL_CPPCORECHECK_WARNINGS
CPPCORECHECK_TYPE_WARNINGS
CPPCORECHECK_RAW_POINTER_WARNINGS
CPPCORECHECK_CONST_WARNINGS
CPPCORECHECK_OWNER_POINTER_WARNINGS
CPPCORECHECK_UNIQUE_POINTER_WARNINGS
CPPCORECHECK_BOUNDS_WARNINGS

這些宏會對應至規則集,並展開為以空格分隔的警告編號清單。 藉由使用適當的 pragma 建構,您可以設定適合專案或程式代碼區段的有效規則集。 在下列範例中,程式代碼分析只會警告遺漏常數修飾詞:

#include <CppCoreCheck\Warnings.h>
#pragma warning(disable: ALL_CPPCORECHECK_WARNINGS)
#pragma warning(default: CPPCORECHECK_CONST_WARNINGS)

屬性

Microsoft C++ 編譯程式對 屬性的支援 [[gsl::suppress]] 有限。 它可用來隱藏函式內的表達式和區塊語句警告。

// Suppress only warnings from the 'r.11' rule in expression.
[[gsl::suppress(r.11)]] new int;

// Suppress all warnings from the 'r' rule group (resource management) in block.
[[gsl::suppress(r)]]
{
    new int;
}

// Suppress only one specific warning number.
// For declarations, you might need to use the surrounding block.
// Macros are not expanded inside of attributes.
// Use plain numbers instead of macros from the warnings.h.
[[gsl::suppress(26400)]]
{
    int *p = new int;
}

使用命令列選項隱藏分析

您可以使用檔案屬性頁中的命令行選項來隱藏專案或單一檔案的警告,而不是 #pragmas。 例如,若要停用檔案的警告 C26400:

  1. 以滑鼠右鍵按兩下 方案總管中的檔案,然後選擇 [屬性]。

  2. 在 [屬性頁] 對話框中,選取 [組態屬性>C/C++>命令行] 屬性頁。

  3. 在 [ 其他選項 ] 編輯方塊中,新增 /wd26400

您可以使用命令列選項,藉由指定 /analyze-來暫時停用檔案的所有程序代碼分析。 您會看到警告 D9025 使用 '/analyze-' 覆寫 '/analyze',這會提醒您稍後重新啟用程序代碼分析。

在特定項目檔上啟用 C++ 核心指導方針檢查程式

有時候,執行專注的程式代碼分析仍然使用Visual Studio IDE 會很有用。 嘗試大型專案的下列範例案例。 它可以節省建置時間,並更輕鬆地篩選結果:

  1. 在命令殼層中,設定 esp.extension 環境變數。

  2. 若要繼承此變數,請從命令殼層開啟Visual Studio。

  3. 載入您的項目並開啟其屬性。

  4. 啟用程式代碼分析、挑選適當的規則集,但未啟用程式代碼分析延伸模組。

  5. 移至您想要使用 C++ 核心指導方針檢查程式分析的檔案,並開啟其屬性。

  6. 選擇組態屬性>C/C++>命令行>其他選項並新增/analyze:plugin EspXEngine.dll

  7. 停用先行編譯標頭的使用(組態屬性>C/C++>先行編譯標頭)。 這是必要的,因為延伸模塊引擎可能會嘗試從先行編譯標頭 (PCH) 讀取其內部資訊。 如果 PCH 是使用預設項目選項編譯的,它將無法相容。

  8. 重建專案。 常見的 PREFast 檢查應該在所有檔案上執行。 因為預設不會啟用 C++ 核心指導方針檢查程式,所以它應該只會在設定為使用它的檔案上執行。

如何使用 Visual Studio 外部的 C++ 核心指導方針檢查程式

您可以在自動化組建中使用 C++ 核心指導方針檢查。

MSBuild

原生程式代碼分析檢查程式 (PREfast) 會由自定義目標檔案整合到 MSBuild 環境中。 您可以使用專案屬性來啟用它,並新增 C++ 核心指導方針檢查程式(這是以 PREfast 為基礎):

  <PropertyGroup>
    <EnableCppCoreCheck>true</EnableCppCoreCheck>
    <CodeAnalysisRuleSet>CppCoreCheckRules.ruleset</CodeAnalysisRuleSet>
    <RunCodeAnalysis>true</RunCodeAnalysis>
  </PropertyGroup>

請務必在匯入 Microsoft.Cpp.targets 檔案之前新增這些屬性。 您可以挑選特定的規則集,或建立自定義規則集。 或者,使用包含其他 PREfast 檢查的預設規則集。

您只能在指定的檔案上執行 C++ 核心檢查程式。 使用與先前所述的相同方法,但使用 MSBuild 檔案。 您可以使用 項目來設定 BuildMacro 環境變數:

<ItemGroup>
    <BuildMacro Include="Esp_Extensions">
      <EnvironmentVariable>true</EnvironmentVariable>
      <Value>CppCoreCheck.dll</Value>
    </BuildMacro>
</ItemGroup>

如果您不想修改項目檔,您可以在命令行上傳遞屬性:

msbuild /p:EnableCppCoreCheck=true /p:RunCodeAnalysis=true /p:CodeAnalysisRuleSet=CppCoreCheckRules.ruleset ...

非 MSBuild 專案

如果您使用不依賴 MSBuild 的組建系統,您仍然可以執行檢查程式。 若要使用它,您必須熟悉程式代碼分析引擎組態的一些內部。 我們並不保證在未來版本的Visual Studio中支援這些內部。

程序代碼分析需要幾個環境變數和編譯程式命令行選項。 建議您使用 Native Tools 命令提示字元 環境,因此您不需要搜尋編譯程式的特定路徑、包含目錄等等。

  • 環境變數

    • set esp.extensions=cppcorecheck.dll 這會告訴引擎載入 C++ 核心指導方針模組。
    • 由於 Visual Studio 2019 不再建議設定環境變數, esp.annotationbuildlevel 因為設定可能會導致誤判。 如果看到非預期的結果,請從您的環境移除此變數。
    • set caexcludepath=%include% 強烈建議您停用在標準標頭上引發的警告。 您可以在這裡新增更多路徑,例如專案中通用標頭的路徑。
  • 命令列選項

    • /analyze 啟用程序代碼分析(也請考慮使用 /analyze:only/analyze:quiet)。
    • /analyze:plugin EspXEngine.dll 此選項會將程式代碼分析延伸模組引擎載入PREfast。 此引擎接著會載入 C++ 核心指導方針檢查程式。

使用指導方針支持連結庫

指導方針支持連結庫 (GSL) 旨在協助您遵循核心指導方針。 GSL 包含定義,可讓您以更安全的替代方案取代容易出錯的建構。 例如,您可以將一 T*, length 組參數取代為 span<T> 類型。 GSL 專案可在 GitHub 上取得 https://github.com/Microsoft/GSL。 連結庫是開放原始碼,因此您可以檢視來源、進行批注或參與。 您也可以使用 vcpkg 套件管理員,在本機下載並安裝連結庫。

在 Visual Studio 2015 專案中使用 C++ 核心檢查指導方針

如果您使用 Visual Studio 2015,預設不會安裝 C++ Core 檢查程式代碼分析規則集。 您必須先執行其他步驟,才能在 Visual Studio 2015 中啟用 C++ Core Check 程式代碼分析工具。 Microsoft 提供 Visual Studio 2015 項目的支援,方法是使用 NuGet 套件。 套件名為 Microsoft.CppCoreCheck,且可在 取得 http://www.nuget.org/packages/Microsoft.CppCoreCheck。 此套件需要您至少已安裝 Visual Studio 2015,且已安裝 Update 1。

套件也會將另一個套件安裝為相依性,也就是僅限標頭的指導方針支持連結庫 (GSL)。 GSL 也可在 GitHub 上取得 https://github.com/Microsoft/GSL

由於程式代碼分析規則在 Visual Studio 2015 中載入的方式,您必須將 Microsoft.CppCoreCheck NuGet 套件安裝到您想要檢查的每個 C++ 專案中。

將 Microsoft.CppCoreCheck 套件新增至 Visual Studio 2015 中的專案

  1. [方案總管] 中,以滑鼠右鍵按下以在您要新增封裝的方案中開啟專案的操作功能表。 選擇 [管理 NuGet 套件] 以開啟 NuGet 封裝管理員

  2. 在 [NuGet 封裝管理員] 視窗中,搜尋 Microsoft.CppCoreCheck。

    Nuget Package Manager window showing the CppCoreCheck package.

  3. 選取 Microsoft.CppCoreCheck 套件,然後選擇 [安裝] 按鈕,將規則新增至您的專案。

    NuGet 套件會將 MSBuild .targets 檔案新增至您在專案上啟用程式代碼分析時叫用的專案。 檔案會將 .targets C++ 核心檢查規則新增為 Visual Studio Code 分析工具的另一個延伸模組。 安裝套件時,您可以使用 [屬性頁] 對話框來啟用或停用已發行和實驗性規則。

另請參閱