用於程式碼分析的 C++ 專案範例
下列程式示範如何建立逐步解說:分析 C/C++ 程式碼的範例 是否有瑕疵 。 這些程序會建立:
名為 CppDemo 的 Visual Studio 解決方案。
名為 CodeDefects 的 靜態程式庫專案。
名為 Annotations 的 靜態程式庫專案。
這些程序也會提供標頭的程式碼,以及用於靜態程式庫的 .cpp 檔案。
建立 CppDemo 解決方案和 CodeDefects 專案
開啟 Visual Studio,然後選取 [ 建立新專案]
在 [ 建立新專案 ] 對話方塊中,將語言篩選準則變更為 C++ 。
選取 [Windows 桌面精靈 ],然後選擇 [ 下一步] 按鈕。
在 [ 設定新專案] 頁面上的 [專案 名稱] 文字方塊中,輸入 CodeDefects 。
在 [ 方案名稱] 文字方塊中,輸入 CppDemo 。
選擇 [建立] 。
在 [ Windows 桌面專案 ] 對話方塊中,將 [應用程式類型 ] 變更為 [靜態程式庫] (.lib)。
在 [其他選項] 下,選取 [空專案] 。
選擇 [ 確定 ] 以建立方案和專案。
開啟 Visual Studio。 在功能表列上,選擇 [檔案]>[新增]>[專案]。
在 [ 新增專案] 對話方塊中,選取 [Visual C++ > Windows Desktop]。
選取 [ Windows 桌面精靈 ]。
在 [ 名稱] 文字方塊中,輸入 CodeDefects 。
在 [ 方案名稱] 文字方塊中,輸入 CppDemo 。
選擇確定。
在 [ Windows 桌面專案 ] 對話方塊中,將 [應用程式類型 ] 變更為 [靜態程式庫] (.lib)。
在 [其他選項] 下,選取 [空專案] 。
選擇 [ 確定 ] 以建立方案和專案。
開啟 Visual Studio。 在功能表列上,選擇 [檔案]>[新增]>[專案]。
在 [ 新增專案] 對話方塊中,選取 [範本 > Visual C++ > Win32]。
選取 [Win32 主控台應用程式 ]。
在 [ 名稱] 文字方塊中,輸入 CodeDefects 。
在 [ 方案名稱] 文字方塊中,輸入 CppDemo 。
選擇確定。
在 [ Win32 應用程式精靈 ] 對話方塊中,選擇 [ 下一步] 按鈕。
將 [ 應用程式類型 ] 變更為 [靜態程式庫 ]。
在 [其他選項] 下 ,取消選取 [先行編譯] 標頭 。
選擇 [完成 ] 以建立方案和專案。
將標頭和來源檔案新增至 CodeDefects 專案
在方案總管中,展開 [CodeDefects ]。
以滑鼠右鍵按一下以開啟標頭檔 的操作功能表 。 選擇 [新增] > [新增項目]。
在 [ 新增專案 ] 對話方塊中,選取 [Visual C++ > Code ],然後選取 [標頭檔][.h]。
在 [ 名稱 ] 編輯方塊中,輸入 Bug.h ,然後選擇 [ 新增 ] 按鈕。
在 Bug.h 的 編輯視窗中,選取並刪除內容。
複製下列程式碼,並將它貼到 編輯器中的 Bug.h 檔案中。
#pragma once #include <windows.h> // Function prototypes bool CheckDomain(wchar_t const *); HRESULT ReadUserAccount(); // These constants define the common sizes of the // user account information throughout the program const int USER_ACCOUNT_LEN = 256; const int ACCOUNT_DOMAIN_LEN = 128;
在方案總管中,以滑鼠右鍵按一下以開啟 [來源檔案 ] 的操作功能表 。 選擇 [新增] > [新增項目]。
在 [加入新項目] 對話方塊中,選取 [C++ 檔 (.cpp)] 。
在 [ 名稱 ] 編輯方塊中,輸入 Bug.cpp ,然後選擇 [ 新增 ] 按鈕。
複製下列程式碼,並將它貼到 編輯器中的 Bug.cpp 檔案中。
#include "Bug.h" // the user account wchar_t g_userAccount[USER_ACCOUNT_LEN] = { L"domain\\user" }; int len = 0; bool CheckDomain(wchar_t const* domain) { return (wcsnlen_s(domain, USER_ACCOUNT_LEN) > 0); } HRESULT ReadUserAccount() { return S_OK; } bool ProcessDomain() { wchar_t* domain = new wchar_t[ACCOUNT_DOMAIN_LEN]; // ReadUserAccount gets a 'domain\user' input from //the user into the global 'g_userAccount' if (ReadUserAccount()) { // Copies part of the string prior to the '\' // character onto the 'domain' buffer for (len = 0; (len < ACCOUNT_DOMAIN_LEN) && (g_userAccount[len] != L'\0'); len++) { if (g_userAccount[len] == L'\\') { // Stops copying on the domain and user separator ('\') break; } domain[len] = g_userAccount[len]; } if ((len = ACCOUNT_DOMAIN_LEN) || (g_userAccount[len] != L'\\')) { // '\' was not found. Invalid domain\user string. delete[] domain; return false; } else { domain[len] = L'\0'; } // Process domain string bool result = CheckDomain(domain); delete[] domain; return result; } return false; } int path_dependent(int n) { int i; int j; if (n == 0) i = 1; else j = 1; return i + j; }
在功能表列上,依序選擇 [檔案]>[全部儲存]。
新增 Annotations 專案並將其設定為靜態程式庫
在方案總管中,以滑鼠右鍵按一下 CppDemo 以開啟操作功能表。 選擇 [ 新增 > 專案]。
在 [ 新增專案 ] 對話方塊中,選取 [Windows 桌面精靈 ],然後選擇 [ 下一步] 按鈕。
在 [ 設定新專案] 頁面上的 [專案 名稱] 文字方塊中, 輸入 注釋 ,然後選擇 [ 建立 ]。
在 [ Windows 桌面專案 ] 對話方塊中,將 [應用程式類型 ] 變更為 [靜態程式庫] (.lib)。
在 [其他選項] 下,選取 [空專案] 。
選擇 [ 確定 ] 以建立專案。
在方案總管中,以滑鼠右鍵按一下 CppDemo 以開啟操作功能表。 選擇 [ 新增 > 專案]。
在 [ 新增專案 ] 對話方塊中,選取 [Visual C++ > Windows Desktop ]。
選取 [ Windows 桌面精靈 ]。
在 [ 名稱] 文字方塊中,輸入 注釋 ,然後選擇 [ 確定 ]。
在 [ Windows 桌面專案 ] 對話方塊中,將 [應用程式類型 ] 變更為 [靜態程式庫] (.lib)。
在 [其他選項] 下,選取 [空專案] 。
選擇 [ 確定 ] 以建立專案。
在方案總管中,以滑鼠右鍵按一下 CppDemo 以開啟操作功能表。 選擇 [ 新增 > 專案]。
在 [ 新增專案 ] 對話方塊中,選取 [Visual C++ > Win32]。
選取 [Win32 主控台應用程式 ]。
在 [ 名稱] 文字方塊中,輸入 注釋 。
選擇確定。
在 [ Win32 應用程式精靈 ] 對話方塊中,選擇 [ 下一步] 按鈕。
將 [ 應用程式類型 ] 變更為 [靜態程式庫 ]。
在 [其他選項] 下 ,取消選取 [先行編譯] 標頭 。
選擇 [ 完成 ] 以建立專案。
將標頭檔和來源檔案新增至 Annotations 專案
在方案總管中,展開 [批註 ]。
以滑鼠右鍵按一下以開啟 [批註 ] 底下的 [標頭檔 ] 操作功能表 。 選擇 [新增] > [新增項目]。
在 [ 新增專案 ] 對話方塊中,選取 [Visual C++ > Code ],然後選取 [標頭檔][.h]。
在 [ 名稱 ] 編輯方塊中,輸入 annotations.h ,然後選擇 [ 新增 ] 按鈕。
在 annotations.h 的 編輯視窗中,選取並刪除內容。
複製下列程式碼,並將它貼到 編輯器中的 annotations.h 檔案中。
#pragma once #include <sal.h> struct LinkedList { struct LinkedList* next; int data; }; typedef struct LinkedList LinkedList; _Ret_maybenull_ LinkedList* AllocateNode();
在方案總管中,以滑鼠右鍵按一下以開啟 [注釋 ] 底下 [來源檔案 ] 的操作功能表 。 選擇 [新增] > [新增項目]。
在 [加入新項目] 對話方塊中,選取 [C++ 檔 (.cpp)] 。
在 [ 名稱 ] 編輯方塊中,輸入 annotations.cpp ,然後選擇 [ 新增 ] 按鈕。
複製下列程式碼,並將它貼到 編輯器中的 annotations.cpp 檔案中。
#include "annotations.h" #include <malloc.h> _Ret_maybenull_ LinkedList* AllocateNode() { LinkedList* result = static_cast<LinkedList*>(malloc(sizeof(LinkedList))); return result; } LinkedList* AddTail(LinkedList* node, int value) { // finds the last node while (node->next != nullptr) { node = node->next; } // appends the new node LinkedList* newNode = AllocateNode(); newNode->data = value; newNode->next = 0; node->next = newNode; return newNode; }
在功能表列上,依序選擇 [檔案]>[全部儲存]。
解決方案現已完成,且應該建置時不會發生錯誤。
注意
在 Visual Studio 2017 中,您可能會在 IntelliSense 引擎中看到虛假警告 E1097 unknown attribute "no_init_all"
。 您可以放心忽略這個警告。