用于代码分析的示例 C++ 项目
以下过程演示如何为演练:分析 C/C++ 代码中的缺陷创建示例。 这些过程将创建:
名为 CppDemo 的 Visual Studio 解决方案。
名为 CodeDefects 的静态库项目。
名为 Annotations 的静态库项目。
这些过程还提供了标头代码以及静态库的 .cpp 文件。
创建 CppDemo 解决方案和 CodeDefects 项目
打开 Visual Studio,选择“新建项目”
在“新建项目”对话框中,将语言筛选器更改为 C++。
选择 “Windows 桌面向导”并选择“下一步”按钮。
在“配置新项目”页面的“项目名称”文本框中输入“CodeDefects”。
在“解决方案名称”文本框中,输入“CppDemo”。
选择“创建”。
在“Windows 桌面项目”对话框中,将“应用程序类型”更改为“静态库 (.lib)”。
在“附加选项” 下,选择“空项目” 。
选择“确定”创建解决方案和项目。
打开 Visual Studio。 在菜单栏上,依次选择“文件”>“新建”>“项目”。
在“新建项目”对话框中,选择“Visual C++”>“Windows 桌面”。
选择“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 桌面”。
选择“Windows 桌面向导”。
在“名称”文本框中,输入“注释”,然后选择“确定”。
在“Windows 桌面项目”对话框中,将“应用程序类型”更改为“静态库 (.lib)”。
在“附加选项” 下,选择“空项目” 。
选择“确定”,创建项目。
在解决方案资源管理器中,右键单击“CppDemo”打开上下文菜单。 选择“添加”>“新建项目”。
在“添加新项目”对话框中,选择“Visual C++”>“Win32”。
选择“Win32 控制台应用程序”。
在“名称”文本框中,输入“注释”。
选择确定。
在“Win32 应用程序向导”对话框中,选择“下一步”按钮。
将“应用程序类型”更改为“静态库”。
在“其他选项”下,取消选择“预编译标头”。
选择“完成”以创建项目。
将头文件和源文件添加到 Annotations 项目
在解决方案资源管理器中,展开“注释”。
右键单击可打开“注释”下“头文件”的上下文菜单。 选择“添加”>“新项” 。
在“添加新项”对话框中,选择“Visual C++”>“Code”,然后选择“头文件 (.h)”。
在“名称”编辑框中,输入“注释.h”,然后选择“添加”按钮。
在“注释.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)” 。
在“名称”编辑框中,输入“注释.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"
。 可以放心地忽略此警告。