演练:对 C/C++ 代码进行缺陷分析
更新:2007 年 11 月
本演练演示如何通过使用 C/C++ 代码分析工具来分析 C/C++ 代码以查找潜在的代码缺陷。
在本演练中,逐步完成使用代码分析来分析 C/C++ 代码以查找潜在代码缺陷的过程。
您将完成下列步骤:
在本机节点上运行代码分析。
分析代码缺陷警告。
将警告视为错误。
批注源代码以改进代码缺陷分析。
先决条件
Visual Studio Team System Development Edition。
演示示例 的副本。
对 C/C++ 进行基本了解。
对本机代码运行代码缺陷分析
在 Development Edition 中打开演示解决方案。
演示解决方案现在将出现在“解决方案资源管理器”中。
在“生成”菜单上单击“重新生成解决方案”。
将生成解决方案,并且不出现任何警告或错误。
在“解决方案资源管理器”中,选择“CodeDefects”项目。
在“项目”菜单上单击“属性”。
将显示“CodeDefects 属性页”对话框。
单击“代码分析”。
从“启用 C/C++ 代码分析”下拉列表中,选择“是(/analyze)”,然后单击“确定”。
重新生成 CodeDefects 项目。
代码分析警告显示在“错误列表”中。
分析代码初始化缺陷警告
在“视图”菜单上单击“错误列表”。
根据您在 Visual Studio 2005 Team System 中选择的开发人员配置文件,可能需要指向“视图”菜单上的“其他窗口”,然后单击“错误列表”。
在“错误列表”中双击下列警告:
警告 C6230:语义不同的类型之间的隐式强制转换: 在 Boolean 上下文中使用 HRESULT。
代码编辑器显示导致在函数 boolProcessDomain() 中出现警告的代码行。该警告指示“if”语句中正在使用 HRESULT,而原本应使用布尔值结果。
通过使用 SUCCEEDED 宏来更正该警告。代码看起来应类似下面这样:
if (SUCCEEDED (ReadUserAccount()) )
在“错误列表”中双击下列警告:
警告 C6282:运算符不正确: 在测试上下文中执行了常数赋值。Was == intended?(事实是否确实像预计的那样?)
通过测试是否等同来更正该警告。代码看起来应类似下面这样:
if ((len == ACCOUNT_DOMAIN_LEN) || (g_userAccount[len] != '\\'))
将警告视为错误
在 Bug.cpp 文件中,将下面的 #pragma 语句添加到文件的开头,将警告 C6001 视为错误:
#pragma warning (error: 6001)
重新生成 CodeDefects 项目。
在“错误列表”中,C6001 现在显示为一个错误。
通过将 i 和 j 初始化为 0,更正“错误列表”中的其余两个 C6001 错误。
重新生成 CodeDefects 项目。
将生成项目,并且不出现任何警告或错误。
更正 annotation.c 中的源代码批注警告
在解决方案资源管理器中,选择 Annotations 项目。
在“项目”菜单上单击“属性”。
将显示“Annotations 属性页”对话框。
单击“代码分析”。
从“启用 C/C++ 代码分析”下拉列表中,选择“是(/analyze)”,然后单击“确定”。
重新生成 Annotations 项目。
在“错误列表”中双击下列警告:
警告 C6011:正在取消 NULL 指针“newNode”的引用。
该警告指示调用方检查返回值失败。在这种情况下,调用 AllocateNode 可能会返回一个 NULL 值(有关 AllocateNode 的函数声明,请参见 annotations.h 头文件)。
打开 Annotation.c 文件。
若要更正该警告,请使用“if”语句来测试返回值。代码看起来应类似下面这样:
if (NULL != newNode)
{
newNode->data = value;
newNode->next = 0;
node->next = newNode;
}
重新生成 Annotations 项目。
将生成项目,并且不出现任何警告或错误。
使用源代码批注
通过使用 Pre 和 Post 条件,批注函数 AddTail 的形参和返回值,如下面的示例所示:
[returnvalue:SA_Post (Null=SA_Maybe)] LinkedList* AddTail
(
[SA_Pre(Null=SA_Maybe)] LinkedList* node,
int value
)
重新生成 Annotations 项目。
在“错误列表”中双击下列警告:
警告 C6011:正在取消 NULL 指针“node”的引用。
该警告指示传递给函数的节点可能为空。
若要更正该警告,请使用“if”语句来测试返回值。代码看起来应类似下面这样:
. . . LinkedList *newNode = NULL; if (NULL == node) { return NULL; . . . }
重新生成 Annotations 项目。
将生成项目,并且不出现任何警告或错误。